1
0
Fork
You've already forked boom
0
No description
  • TypeScript 89.6%
  • CSS 7.9%
  • JavaScript 1.3%
  • HTML 1%
  • Shell 0.2%
Jacqueline ccf768a093 Spotify view: compare playlists against the library, build a 'missing' playlist
New sidebar view that talks to the Spotify Web API from the main process
(renderer CSP stays closed). Search public playlists, list a user's public
playlists (user:<name> or profile URL — Spotify search doesn't index small
personal playlists), or paste a playlist link. Tracks are matched against the
loaded session with the scan pipeline's own normalization: exact artist+title
first, then Dice fuzzy (>= 0.82) over tags and filenames, duration-gated.
Each track shows have/missing, with All/Have/Missing filters and CSV export
of the missing ones.
Reads use the client-credentials flow with the user's own app credentials
(persisted in settings; secret never reaches the renderer). "New Spotify
playlist from missing" needs a user token: one-time Authorization Code + PKCE
browser login with a short-lived callback server on 127.0.0.1:8888, refresh
token persisted separately in userData/spotify-auth.json so persistSettings
can't clobber it. Creates a private playlist in 100-URI chunks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026年07月12日 22:32:13 +02:00
build Default Track Table to newest-added first; recolor icon to purple 2026年06月18日 07:35:52 +02:00
sample-data Complete 2026年06月14日 08:02:25 +02:00
scripts Default Track Table to newest-added first; recolor icon to purple 2026年06月18日 07:35:52 +02:00
src Spotify view: compare playlists against the library, build a 'missing' playlist 2026年07月12日 22:32:13 +02:00
.gitignore Stop tracking .claude/settings.local.json (local config); ignore build scratch files 2026年06月14日 16:40:34 +00:00
_validate_web.mjs README 2026年06月14日 17:47:06 +02:00
ARCHITECTURE.md Spotify view: compare playlists against the library, build a 'missing' playlist 2026年07月12日 22:32:13 +02:00
electron-builder.yml Complete 2026年06月14日 08:02:25 +02:00
electron.vite.config.1781421717924.mjs README 2026年06月14日 17:47:06 +02:00
electron.vite.config.1781421727264.mjs README 2026年06月14日 17:47:06 +02:00
electron.vite.config.ts Complete 2026年06月14日 08:02:25 +02:00
package-lock.json Phase 2: Transition Prep Mode - two-deck waveforms with in/out markers 2026年06月14日 07:24:11 +00:00
package.json Phase 2: Transition Prep Mode - two-deck waveforms with in/out markers 2026年06月14日 07:24:11 +00:00
README.md Add Trash button on duplicate copies (move to system Trash, recoverable) 2026年06月14日 17:17:04 +00:00
TRANSITION_PREP_PLAN.md Phase 1: persistent in/out transition markers + remove em dashes 2026年06月14日 07:18:29 +00:00
tsconfig.json Complete 2026年06月14日 08:02:25 +02:00
tsconfig.node.json Complete 2026年06月14日 08:02:25 +02:00
tsconfig.web.json Complete 2026年06月14日 08:02:25 +02:00

Boom

A local-first desktop app that sits between Rekordbox and your music folder. It detects duplicates, inspects tracks, and compares what's in Rekordbox against what's on disk - built for a DJ workflow, not a generic file browser.

Boom never writes to your Rekordbox library or your file tags - it only reads the XML export and your folder. The one file action it offers is moving a duplicate to the system Trash (recoverable), and only when you click Trash on a specific file. Nothing else is moved, renamed, retagged, or deleted.

views


What it does

  1. Load your Rekordbox XML export (the canonical source for playlists, BPM, and key).
  2. Scan a local music folder (.mp3 .flac .wav .aiff .aif .m4a).
  3. Match folder files to Rekordbox entries with layered strategies.
  4. Detect duplicates in layers (path → metadata → filename → fuzzy → optional acoustic fingerprint).
  5. Browse everything in a fast, sortable, filterable table.
  6. Review playlists from the XML (with misc pinned to the top).
  7. Compare "in folder but not in Rekordbox", "in Rekordbox but missing on disk", and "missing BPM/key".
  8. Export CSV / JSON reports (all tracks, duplicate groups, mismatches, a delete-candidates list, selected rows), and save/load scan sessions.
  9. Curate locally with staging playlists and custom tags that are never written to Rekordbox or your files.
  10. Mix harmonically - for any track, see compatible tracks by Camelot key + BPM.
  11. Preview audio - play any track on disk in a built-in player with seeking.
  12. Prep transitions in a two-deck mode: beatmatch and phrase-sync two tracks on your Rekordbox beatgrids, with in/out markers, master BPM, keylock, and a crossfader.

Audio preview

Click ▶ Play in the inspector (or double-click a row in the Track Table, or use ▶ on a duplicate row) to preview a track in the bottom player bar - full native transport with seeking. Files stream through a dedicated, range-enabled boom-audio:// protocol restricted to recognized audio files, so nothing is copied and large files seek instantly. Playback is read-only.

Transition Prep (two-deck beatmatch)

A two-deck mode for auditioning transitions and finding the right bar to mix on. It is built entirely on your Rekordbox beatgrid (the <TEMPO> anchors in the XML), so beats, bars, and phrase guides line up with the actual music. Like the rest of Boom it is read-only: markers and deck state are saved locally, never written to Rekordbox or your audio.

Open it from the Transition Prep view in the sidebar, or load a track straight onto a deck with the A / B buttons in the Track Table, or the Deck A / Deck B buttons in the inspector.

Each deck shows:

  • A zoomed-in detail waveform (opens at ~3 bars) with the beatgrid drawn on top: every beat, stronger lines on each bar, and a prominent marker every 8 bars (toggle 8 / 16 / off). Bar.beat numbers appear as you zoom in, and a full-song overview strip sits below for navigation.
  • BPM and Key from the Rekordbox grid, plus a fixed red center line. Drag the waveform to jog a beat onto the line; the start gets blank lead-in space so even bar 1.1 can sit on it.
  • Persistent IN / OUT markers (where the track comes in and mixes out), saved per track and kept across reloads.

Mixing controls:

  • Beat Sync (on by default): start a deck while the other is playing and it snaps to the nearest bar and stays locked, with a continuous correction loop holding the two in phase. The blue Sync button does it in one click and starts the deck for you.
  • Master BPM: pin both decks to a common tempo (set 128 and a 126 and a 130 track both play at 128). Quick-set from either deck's native BPM, or turn it off.
  • Keylock per deck preserves pitch when the tempo is stretched.
  • A crossfader blends between A and B, and a live offset readout ("on beat" / "off +0.30 beat") shows the lock.

Both decks can play at once. Beat sync is a feedback loop over the browser's audio clock, so it holds within a few milliseconds rather than being sample-perfect, which is plenty for curating and prepping sets. The last XML and folder auto-load and scan on launch, and the two decks reload their tracks and markers where you left them (saved in settings.json and annotations.json under the app's user-data folder).

Local curation (staging playlists + custom tags)

Boom keeps a local annotation layer that never touches Rekordbox or your audio files:

  • Staging playlists - create local playlists in the Playlists view ("Staging (local)"). Select tracks in the Track Table and use the Add ... to staging dropdown, or toggle membership per track in the inspector. Click a staging playlist to filter the table to it.
  • Custom tags - add free-form tags to any track in the inspector. Tags show in the Track Table "Tags" column, are included in search, and appear in CSV exports.

These persist across rescans in ~/Library/Application Support/Boom/annotations.json (keyed by a stable per-file id), so they survive re-scanning your folder. Nothing here is ever imported into Rekordbox.

Harmonic matching ("Mix with")

Select any track and the inspector lists harmonically compatible tracks - same key, ±1 on the Camelot wheel, the relative major/minor, or a +2 energy boost - whose BPM is within 6% (also accepting double/half-time). Results are sorted by key relation then BPM closeness; click one to inspect it. Toggle Camelot in the toolbar to show Camelot codes everywhere.

Build a set from matches: in the "Mix with" section, pick a target playlist (or create one inline), then use + on any match to add it, or + Add all to add the seed track plus every compatible match to that staging playlist at once. This is the fast way to curate a key/BPM-matched playlist inside Boom - no Rekordbox involved.

BPM & Key sourcing

Rekordbox XML is treated as canonical for analyzed BPM and key. File tags are used only as a fallback when the XML has no value (or when a file isn't in Rekordbox at all). The inspector shows which source won (RB vs TAG) for every track. This matches reality: in a typical library most files carry no BPM/key in their tags, so the XML is the reliable source.


Quick start

Requires Node 18+ (tested on Node 26) and macOS / Windows / Linux.

npm install
npm run dev

Then in the app:

  1. Click Choose XML... and select your Rekordbox XML export.
  2. Click Choose Folder... and select your misc folder. (On this machine it defaults to /Users/jacqueline/Documents/music/misc.)
  3. Click Scan.

You can also try it immediately with the bundled sample data:

  • XML: sample-data/sample-rekordbox.xml
  • Folder: sample-data/misc

The sample set intentionally contains duplicates (same track as FLAC + MP3, a (1) copy, a - copy file) and one Rekordbox entry whose file is missing on disk, so every view has something to show.

Exporting a Rekordbox XML

In Rekordbox: File → Export Collection in xml format (or Preferences → Advanced → Database → rekordbox xml, then File → Export). Boom reads that file; it never writes to it.


Scripts

Command Description
npm run dev Run the app in development with hot reload.
npm run build Production build into out/.
npm run build:mac Build a macOS app + DMG into dist/ (Apple Silicon).
npm run make:icon Regenerate build/icon.icns + icon.png from the Boom mark.
npm start Preview the production build.
npm run typecheck Type-check main + renderer projects.

Building a Mac app

npm run build:mac

Produces dist/Boom-<version>-arm64.dmg and dist/mac-arm64/Boom.app. The build is unsigned (no Apple Developer certificate), so the first time you open it macOS Gatekeeper will block it - right-click the app → Open → Open, or run xattr -dr com.apple.quarantine /Applications/Boom.app after dragging it from the DMG. Subsequent launches are normal.


Main screens

  • Library Overview - counts for files, Rekordbox tracks, matched, duplicate groups, folder-only, Rekordbox-only, missing files, and missing BPM/key. Cards are clickable and jump to a filtered view.
  • Track Table - every track with Artist, Title, Filename, Format, Duration, BPM, Key, In-Rekordbox, Playlists, Duplicate, Confidence, Reason, Path. Sortable on any column, text search, filter chips, multi-select (⌘/⇧-click), sticky header, row virtualization for large libraries.
  • Duplicates - groups with side-by-side comparison, the recommended file to keep (★), and per-group "mark reviewed". Header shows how many delete candidates exist and the reclaimable space, with "Export report" and "Export delete candidates" buttons.
  • Playlists - the Rekordbox playlist tree with track counts; click to filter the table; misc pinned at the top.
  • Mismatch - three tabs: in-folder-not-Rekordbox, in-Rekordbox-file-missing, and missing-BPM/key.
  • Transition Prep - two decks with beatgrid waveforms, beat/phrase sync, master BPM, keylock, crossfader, and persistent in/out markers (see above).

Selecting a track opens the inspector on the right: file info, tag metadata, Rekordbox metadata, playlist membership, issues, and the duplicate comparison.

Keyboard / UX

  • Sort: click a column header (click again to flip direction).
  • Multi-select rows: ⌘-click to toggle, ⇧-click for a range. With a selection, Export selected (N) writes just those rows to CSV.
  • Camelot toggle in the toolbar switches key display to the Camelot wheel.
  • Fuzzy toggle enables/disables the slower fuzzy duplicate stage.
  • Fingerprint toggle enables acoustic-fingerprint duplicate matching (see below).
  • ? button (top-right of the toolbar) opens a help panel listing every feature and where to find it. Press Esc or click outside to close.

Acoustic fingerprinting (optional)

Boom can confirm duplicates by how they sound, not just by names/tags - useful for catching the same track under different filenames, or different rips of the same recording. This is off by default and requires Chromaprint's fpcalc on your PATH:

brew install chromaprint # macOS
sudo apt install libchromaprint-tools # Debian/Ubuntu

Tick Fingerprint in the toolbar, then scan. Boom fingerprints the first ~120 s of each folder file (concurrency-limited, so it's slower) and adds a high-confidence "Acoustic fingerprint match" stage to duplicate detection. If fpcalc isn't installed, Boom simply skips this stage and tells you - nothing else is affected.

Fingerprints are cached in fingerprints.json under the app's user-data folder and reused on later scans; a file is only re-fingerprinted when its size or modified-time changes. So the first fingerprint scan is the slow one, and re-scans are fast. The progress banner shows how many were new vs. reused.

Because macOS GUI apps don't inherit your shell PATH, Boom looks for fpcalc in the usual Homebrew/MacPorts locations (/opt/homebrew/bin, /usr/local/bin, /opt/local/bin, /usr/bin) in addition to PATH. If yours lives elsewhere, set the BOOM_FPCALC environment variable to its full path. Toggling Fingerprint off/on re-checks, so no relaunch is needed after installing it.


Safety

  • Never writes to Rekordbox or your file tags. The only file action is Trash on a duplicate copy, which uses the OS Trash/Recycle Bin (recoverable) and is triggered per file by you.
  • Electron security: contextIsolation: true, nodeIntegration: false. All file access, dialogs, and the scan pipeline run in the main process and are reached only through a typed preload bridge (window.boom). A strict Content-Security-Policy is set on the renderer.

Tech stack

Electron + React + TypeScript, built with electron-vite.

  • fast-xml-parser - Rekordbox XML (collection, playlists, and <TEMPO> beatgrids)
  • music-metadata - audio tag/format reading
  • @tanstack/react-virtual - table virtualization
  • wavesurfer.js - deck waveforms, overview minimap, and in/out region markers
  • zustand - renderer state

See ARCHITECTURE.md for how parsing, matching, duplicate detection, and the keep-recommendation work, plus where to add acoustic fingerprinting later.