DJ Assist is a desktop music-library tool for DJs. It scans local music folders, analyzes BPM and musical key, enriches tracks with Spotify and album-art data, imports audio metadata from Google Drive, and helps build playlists with compatibility-aware recommendations.
- Features
- Screenshots
- Architecture
- Requirements
- Installation
- Running The App
- Configuration
- CLI Reference
- API Reference
- Building For Distribution
- Troubleshooting
- Additional Docs
- local folder scanning, watch folders, scan history, validation, cancel, and multiple rescan modes
- BPM, key, bitrate, duration, decode-failure, Spotify fallback, AcoustID, and album-art enrichment
- Google desktop sign-in, Google Drive folder browser, Drive preview, Drive import, local Drive caching, and staged import progress
- local and Google Drive playback with waveform scrubbing, cue points, mute, album art, and YouTube links
- full-text search, artist/album browsing, related tracks, smart crates, command palette, and keyboard shortcuts
- playlist creation and editing with compatibility-aware next-track recommendations
- bulk actions for tags, ignore state, delete, add-to-playlist, BPM reanalysis, and artwork refresh
- runtime diagnostics, startup diagnostics, preferences, source preference switching, activity logs, and library reset
DJ Assist is an Electron desktop app with three main layers:
Electron shell
└── Next.js 15 UI + API server (TypeScript / Node 22)
└── Python 3.11 analysis engine
└── SQLite or PostgreSQL data store
| Layer | Tech | Role |
|---|---|---|
| Desktop shell | Electron 41 | Window lifecycle, IPC, app startup, desktop integrations |
| UI | React 19 + Next.js 15 | Library views, playback UI, modals, progress surfaces |
| API | Next.js API routes | Track, scan, auth, Drive, settings, playlist, and log endpoints |
| Analysis engine | Python 3.11 | Scanning, BPM/key analysis, metadata extraction, CLI |
| Database | SQLite by default, PostgreSQL optional | Tracks, playlists, scan jobs, settings-backed workflows |
The backend stays running when the Electron window closes. Reopening the window reconnects to the same backend and restores running jobs from history.
- macOS is the primary supported platform
- Node 22.x
- Python 3.11+
- SQLite on macOS, or PostgreSQL if you intentionally configure server-style storage
brew install node@22 python@3.11Confirm versions:
node -v
python3 --versiongit clone <repo-url> dj-assist
cd dj-assist
npm installpython3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -r requirements.txtmkdir -p ~/.dj_assistCreate .env.local:
DJ_ASSIST_DB_PATH=/Users/<you>/.dj_assist/dj-assist.db
PYTHON_EXECUTABLE=/Users/<you>/Projects/dj-assist/.venv/bin/pythonIf you plan to use Google Drive, Spotify, or server sync, also configure the relevant variables from the table below.
npm run devThis launches Electron and the embedded Next.js backend together.
npm run backend:devThen open http://localhost:3000.
- Open
Collection. - Check
Startup Diagnostics. - Add a local music folder or open
Add Music. - Run a local scan or import Google Drive metadata.
- Open a track and verify playback, waveform, and metadata.
All configuration is driven through environment variables, typically from .env.local.
| Variable | Default | Description |
|---|---|---|
DJ_ASSIST_DB_PATH |
~/.dj_assist/dj-assist.db |
Local SQLite database path |
DJ_ASSIST_DATABASE_URL |
— | PostgreSQL connection string; overrides SQLite |
PYTHON_EXECUTABLE |
python3 |
Python used by scan and analysis routes |
GOOGLE_CLIENT_ID |
— | Google OAuth desktop client ID |
GOOGLE_CLIENT_SECRET |
— | Google OAuth desktop client secret for local dev flows |
SPOTIFY_CLIENT_ID |
— | Spotify API client ID |
SPOTIFY_CLIENT_SECRET |
— | Spotify API client secret |
ACOUSTID_API_KEY |
— | AcoustID API key |
FPCALC_PATH |
system lookup | AcoustID fingerprint executable path |
DJ_ASSIST_SERVER_ENABLED |
false |
Enable optional server sync features |
DJ_ASSIST_SERVER_URL |
— | Production server URL |
DJ_ASSIST_LOCAL_SERVER_URL |
http://localhost:3001 |
Local server URL used when local debug mode is enabled |
DJ_ASSIST_SERVER_LOCAL_DEBUG |
false |
Switch server sync calls to the local server URL |
DJ_ASSIST_ELECTRON_PORT |
3000 |
Embedded Next.js port |
DJ_ASSIST_ELECTRON_HOST |
127.0.0.1 |
Embedded Next.js host |
DJ_ASSIST_PYTHON_STANDALONE |
— | Relocatable Python root used for packaging |
DJ_ASSIST_CONFIG_DIR |
app-managed default | Config, logs, cache, and waveform base directory |
Google sign-in expects a Google OAuth client of type Desktop app.
The Python package exposes python -m dj_assist.cli and related commands.
dj-assist scan <directory>| Option | Description |
|---|---|
--mode smart |
Scan new and changed files |
--mode full |
Rescan all files |
--mode missing-metadata |
Only files missing Spotify metadata |
--mode missing-analysis |
Only files missing BPM/key |
--mode missing-art |
Only files missing album art |
--fetch-art |
Fetch album art during scan |
--verbose |
Verbose diagnostic output |
dj-assist list
dj-assist search --query "track name"
dj-assist search --artist "Artist"
dj-assist search --key 8A
dj-assist search --bpm-min 120 --bpm-max 130
dj-assist debug <track_id>
dj-assist reanalyze-bpm <track_id>
dj-assist waveform-peaks <file>
dj-assist fetch-art
dj-assist fetch-art --force
dj-assist fetch-art --limit 50dj-assist write-tags <file> \
--artist "Artist" \
--title "Track Title" \
--album "Album" \
--key 8A \
--tags "dark,peak-time"dj-assist set new "My Set Name"
dj-assist set list
dj-assist set show <set_id>
dj-assist set add <set_id> <track_id>
dj-assist set remove <set_id> <pos>
dj-assist set recommend <set_id>
dj-assist set export <set_id>dj-assist dedupe
dj-assist dedupe --dry-run
dj-assist reset-db
dj-assist reset-db --yes
dj-assist flow
dj-assist webBase URL: http://127.0.0.1:3000/api
| Method | Path | Description |
|---|---|---|
GET |
/api/auth/google/start |
Start Google OAuth desktop flow |
GET |
/api/auth/google/callback |
Complete Google OAuth callback |
POST |
/api/auth/logout |
Clear current Google session |
| Method | Path | Description |
|---|---|---|
GET |
/api/google-drive/folders |
Browse Drive folders |
GET |
/api/google-drive/files |
List audio files visible to the current Drive scope |
POST |
/api/google-drive/import |
Import Drive metadata into DJ Assist |
| Method | Path | Description |
|---|---|---|
GET |
/api/scan |
List scan jobs |
POST |
/api/scan |
Start a scan |
GET |
/api/scan/:id |
Fetch scan job detail |
GET |
/api/scan/:id/stream |
Stream scan progress |
POST |
/api/scan/validate |
Validate a scan directory |
| Method | Path | Description |
|---|---|---|
GET |
/api/tracks |
List tracks with filters |
GET |
/api/tracks/:id |
Fetch track detail |
PATCH |
/api/tracks/:id |
Update track metadata |
GET |
/api/tracks/:id/stream |
Stream track audio |
GET |
/api/tracks/:id/waveform |
Fetch waveform peak data |
GET |
/api/tracks/:id/next |
Fetch next-track recommendations |
POST |
/api/tracks/:id/reanalyze-bpm |
Re-run BPM analysis |
POST |
/api/tracks/:id/reanalyze-art |
Re-run artwork analysis |
GET |
/api/tracks/:id/art |
Resolve or stream track artwork |
POST |
/api/tracks/bulk |
Run bulk actions on selected tracks |
| Method | Path | Description |
|---|---|---|
GET |
/api/sets |
List playlists |
POST |
/api/sets |
Create playlist |
GET |
/api/sets/:id |
Fetch playlist with tracks |
PATCH |
/api/sets/:id |
Rename playlist |
POST |
/api/sets/:id/tracks |
Add track to playlist |
DELETE |
/api/sets/:id/tracks/:position |
Remove playlist item |
| Method | Path | Description |
|---|---|---|
GET |
/api/library |
Collection overview and health metrics |
POST |
/api/library/reset |
Reset local library data |
POST |
/api/settings/spotify |
Save Spotify settings |
POST |
/api/settings/google |
Save Google OAuth settings |
POST |
/api/settings/server |
Save server sync settings |
| Method | Path | Description |
|---|---|---|
GET |
/api/watch |
List watch folders |
POST |
/api/watch |
Add watch folder |
DELETE |
/api/watch |
Remove watch folder |
GET |
/api/health |
Runtime health and startup diagnostics |
GET |
/api/logs/client |
Read client diagnostic logs |
POST |
/api/logs/client |
Append client diagnostic log entries |
npm run build
npm run pack:macexport DJ_ASSIST_PYTHON_STANDALONE=/absolute/path/to/relocatable-python-root
npm run dist:macFor signed and notarized builds, also set:
export APPLE_ID=you@example.com
export APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx
export APPLE_TEAM_ID=XXXXXXXXXXArtifacts are written to dist-electron/.
Packaging copies the Python runtime, prepares bundled audio tools, builds the Next.js app, and runs electron-builder.
Open Collection → Startup Diagnostics. Verify the Python runtime, database path, and audio tools.
source .venv/bin/activate
python -m dj_assist.cli --help
python -m dj_assist.cli scan /path/to/musicVerify .env.local and confirm DJ_ASSIST_DB_PATH or DJ_ASSIST_DATABASE_URL points to a writable and reachable target.
- verify Google sign-in is active
- open the Drive folder picker and reduce the scope to a smaller folder
- check
Collectionand the activity logs for Drive import progress and failures
curl -I http://127.0.0.1:3000/api/tracks/<id>/streamFor Google Drive-backed tracks, the first play may need to create a local cache copy before waveform or playback becomes available.
Add Spotify credentials and rerun:
SPOTIFY_CLIENT_ID=...
SPOTIFY_CLIENT_SECRET=...or re-run a targeted scan with --mode missing-metadata.
Right-click the app in Finder, choose Open, and confirm. You can also allow it from System Settings → Privacy & Security.




