FAQ
Short answers. A DJ's questions first, then an engineer's.
Before you load a track.
Is it free?
Yes. Nothing is behind a paywall, and the code is Apache-2.0 licensed. The project's rule for any future paid feature, in Alex Foster's words:
“a paid feature must be one that needs a server you run, and then it enforces itself with no DRM at all.”
In a prompt to the build agents, Mon 31 Aug 2026. In plain terms: anything that might one day cost money will be something that needs a server, like cloud sync; nothing in the app on your Mac will be locked.
Will it change my rekordbox library?
No. The installed Mac app clears the write switch before its engine starts, so it will not write to your rekordbox library, a Pioneer share or a USB export; its one library write is a djay playlist write-back, which runs only after you confirm it and backs up the playlist first. It copies rekordbox's database file and reads only the copy. From a source checkout, writes are off by default; the one exception is undo of an earlier write you allowed. rekordbox encrypts that file, so the copy is decrypted with pyrekordbox, the open-source library Open DJ uses to read it. Cues you set in Open DJ stay in Open DJ, and saving new ones is built but not yet tested on a real library: nothing goes back to rekordbox or to a USB stick in this alpha, so you cannot prepare club USBs with it yet.
Developers running from source have command-line writers. Their rekordbox and djay writes go through these rails, so no single mistake can corrupt a library. The Traktor writer has only the dry run and two explicit flags, with no running-app check, backup, atomic write or read-back, and the Serato and Traktor writers are tested on synthetic files only, so do not run them against your real library. More on the Migrate page.
- You type a non-trivial confirmation string.
- It refuses to write while the target app is running. In rare setups this check can miss, so quit the other app yourself before any write.
- It makes a timestamped backup of every file it will change.
- Dry run is the default. A live write needs two explicit flags.
- The write is atomic, one database transaction or a temp file renamed into place, never half-written.
- It reads the result back to verify it, and emits a script that reverses the change.
Back up your libraries before a first run anyway.
Can I play a gig on it?
Not yet. It is an alpha, the first public test release. Try the four-deck screen on your own library at home, use it to find missing files, and keep rekordbox for paid gigs for now. The features page lists what works and what does not.
What happens if it crashes mid-set?
A crash can stop the music. While anything plays, Open DJ saves where your decks are to disk, at most every 2 seconds. Reopen it within 10 minutes and the decks come back and play on from where the track would be by now, on the beat, with one Undo. After longer than that, up to 24 hours, it restores your decks, cues, EQ and faders without playing anything. While a deck is playing, Cmd-Q asks before it quits.
Where do I start?
Download the app, open it, and setup finds your rekordbox library and imports it, with progress on screen. Quit rekordbox first so the import has your latest changes. No rekordbox? Point it at a music folder. Then load a track from the library onto a deck. The download page has the details.
Which operating systems?
macOS on Apple silicon. It is the only build. Windows and Linux get a download button only when a tested build exists. See Platforms.
Which controllers work?
MIDI controllers are not supported in the Mac app in this alpha: it runs in macOS's own web view, which has no WebMIDI, so it works with mouse and keyboard. They work in Chrome or Edge only when you run Open DJ from a source checkout; the steps are on the download page.
The Pioneer DDJ-400 has been played live that way. A DDJ-FLX4 map passed a first hardware round. Maps for the DDJ-FLX10 and Reloop Mixtour exist, and the project has no record of them being played in a set. Other controllers need a map; a learn log shows what each control sends. Controller status
How is it different from Mixxx?
Mixxx is the established open-source DJ app and has been developed since 2001. Open DJ is a much younger project. What it focuses on: a four-deck screen laid out like rekordbox, importing the rekordbox library you already have without changing it, a library view that shows missing files, stems and lyrics inside the deck, and a command surface that scripts and agents can drive.
Is it a rekordbox replacement?
Not today. rekordbox is the AlphaTheta (Pioneer DJ) app. Open DJ keeps a screen layout working DJs already know and imports the rekordbox library you already have, without changing it, so you can run both. It is local-first and independent, and it is not affiliated with AlphaTheta.
Why "alpha"?
It is early software, and 1.0 alpha means the first public test release, not a finished one. It runs on one platform, the Mac app cannot use a MIDI controller yet, stems are made outside the app, several features are partial, and some controller maps have not been played live. The app's own audio output pickers do not work in this build, so set the output in macOS Sound settings. There are no effects beyond the channel filter and no sampler; both are planned controls that show as not built. The features page lists what works and what does not.
How do I report a bug?
There is no public bug tracker for this alpha yet; a contact route will be announced on this site shortly after release. For a security problem, see Security; hello@open-dj.com works once its forwarding is verified (Press). If you accept the test-user terms, the app sends error reports and a recording of the session with all text masked, no audio and no artwork; track names and file paths are stripped out. See Privacy.
Is this the OpenDJ LDAP server?
No. Open DJ is DJ software. OpenDJ is an unrelated LDAP directory server, and the two projects have no connection.
Before you read the code.
What do "typed commands" and "agent-drivable" mean?
Every deck and mixer control goes through one command bus. PerformanceCommand is a TypeScript discriminated union on type, handled by a single dispatcher with an exhaustive switch and validated on the wire with exact keys, so an unknown field is rejected, not ignored. UI clicks, MIDI mappings and agents emit the same commands; there is no separate automation path. The bus is exposed as POST /api/v1/commands, with state readable at GET /api/v1/state/ui-mirror, and wrapped by the opendj CLI and the opendj mcp server. A parity test fails if the CLI's verb table and the union drift apart. Most deck and mixer controls are on the bus, including master volume and mute; some UI-only state, such as drawer and overlay open/closed, is still component-local.
type PerformanceCommand =
| { type: 'fader'; deck: DeckId; value: number }
| { type: 'play'; deck: DeckId; playing: boolean; quantize?: boolean }
| { type: 'crossfader'; value: number }
| ...
What is the open-dj format?
A JSON document validated against a JSON Schema (Draft 2020-12) and written in RFC 8785 canonical form (JCS), so the same library always serializes to the same bytes and hashes the same. Every analyzed value is an envelope, {value, source, confidence?, modified_at}, where modified_at is when the source last changed the value, not when the export ran. Two apps that disagree about a BPM leave two values in the data instead of one overwrite. The reference code is apps/open_dj: python -m apps.open_dj.cli with validate, canon, diff (keyed on track_id), export and import through a vendor adapter (an import is a dry run unless you pass --live), and conformance, which runs the corpus in open-dj/conformance/. The spec and schemas are CC BY 4.0; the code is Apache-2.0. The spec is at 0.2-draft and will break before 1.0. More
Does it need an account or the internet?
No. Sign-in is optional: POST /api/v1/auth/login starts a Google OAuth flow that asks for openid email profile and nothing else. Two features check it. The stems relay verifies the Google ID token with Google, then checks a tester allowlist and a rate cap before it runs a job. Enrolling a machine in a CloudSync hub presents a Google ID token that the hub verifies (signature, issuer, audience, lifetime). The library stays in a local data directory. Without sign-in, three things still reach the network on their own: LRCLIB for lyrics (artist, title and duration), MusicBrainz and then the Cover Art Archive for missing cover art when a track loads (title and first artist), and GET /api/v1/update/check, which reads the release manifest on GitHub each time the window opens. The privacy page lists what goes where.
Where is the source?
On GitHub at github.com/alex-foster-personal/opendj, a public mirror of the working repository, public since Wed 7 Oct 2026 (Contributing). The build-from-source steps are on the download page.
How did one person build it?
Issues in the private working repository are the queue. Agent workers take issues in parallel, and each one opens a pull request. An AI reviewer must have reviewed the current head: Codex, or one of the other models in EXPECTED_REVIEWERS (scripts/review_coverage.py), which just review <PR> runs in turn as a fallback chain (scripts/review_chain.py). just review-triage <PR> fails when no reviewer left an artifact at that head or a review thread has no disposition. Merges to main go only through the Trunk merge queue, configured as code in ci/trunk-merge-queue.json with direct merges off: the queue tests each pull request merged onto its current head, in batches that it bisects on a failure, and merges only when ci gate and e2e verdict pass on that tree. The library layer came first, in April; the performance rig was built mostly in August and September. How it was built, with the numbers