Harmonic mixing intelligence for your Spotify crates.
KeyTrack turns your Spotify library into a DJ's workspace β it reads the key, BPM, and energy of every track and lays them out so you can mix in key, dig through crates, and build sets, all in the browser.
This is a tool I began in 2019β2020 while I was still in college, to help me build sets for DJ gigs and shows. I always liked to save new music on Spotify through playlists, but when building setlists I found myself having to compile music and feed it into BPM/key detection or DJ software, which was very time consuming. KeyTrack started out as a fun side project to learn more about APIs and backends while doing something I loved.
I followed a Spotify Developer API tutorial on YouTube, then designed and created the very first few iterations of KeyTrack. Those early versions included the "Current Song" feature that could detect BPM and key for a song you were currently playing on Spotify, as well as pull your playlists and tracks and display their musical information on Material-UI surfaces. I built out the core of the search, filter, and backend server functionality between 2020 and 2025.
With the rise of AI and agentic coding, I was able to use Cursor in 2025 to build out a recommendations feature and redesign parts of the UI. And with Claude in 2026, I was able to do a full UI revamp and introduce a ton of new features I've always wanted to see.
It's a project I hold very dear to me, and I hope it's helpful to you! :)
Side note: Everything below here is written by Claude, with my guidance of course.
At its core, KeyTrack answers the question every DJ asks while digging: "what mixes with this?" It reads Spotify's audio analysis β and computes its own for SoundCloud β translating both into the language DJs actually use: Camelot keys, BPM, energy, even chord loops. Then it gives you the tools to find, organize, and sequence music harmonically, across both libraries at once. Here's the full picture.
KeyTrack detects the musical key and tempo of every track from Spotify's audio features, then lets you read keys in whichever system you think in. Flip any key column between Musical (C, Aβmβ¦), Camelot (8B, 5Aβ¦), and Open Key notation on the fly β no mental conversion required.
The standalone Key Calculator is an interactive Camelot wheel: tap a key and instantly see it in all three notations alongside its harmonic neighbors. It works without even logging in.
Connect SoundCloud alongside Spotify and dig both libraries in one place. SoundCloud has no public audio-analysis API, so KeyTrack computes the key and BPM itself β a dedicated analysis service decodes each track, runs proper key + tempo detection, and caches the result so it's only ever analyzed once. Open a SoundCloud crate on its own, or combine Spotify + SoundCloud into one crate (a greenβorange header marks the mix) and sequence across both as if they were a single library. Tempo read a little off on a tooly track? Correct any BPM in a tap.
For SoundCloud tracks, KeyTrack goes a step past the key and detects the repeating chord loop β the few chords of the song, in order β so you've got the actual harmony for mashups, edits, and key changes. It shows in the Now Playing and behind a βͺ on each row; busy, chord-less tracks simply don't show one.
Every key in your library is color-coded by its Camelot position, so compatible tracks visually rhyme. Anchor a track and KeyTrack lights up every harmonic match β same key, Β±1 on the wheel, and the relative major/minor β while dimming the clashes. Filter a crate down to just the keys you want with a tap-friendly Camelot wheel or piano picker, and pair it all with the per-track energy meter to build a flow that's both in key and on vibe.
Your playlists become a visual, cover-art crate library you can actually navigate. Switch between Crates and Folders, sort / filter / search, and tame big libraries with pagination. Make it yours with tags, genres, favorites, hiding, and true folders, and reach your Liked Songs as a crate of their own. Need to dig wide? Tap crates to select them (or Select all) and open many at once as a single combined view.
Open Crate DNA to see a crate's character in seconds: its key distribution as Camelot bars, a BPM histogram, and a summary of track count, BPM range, dominant key, the major/minor split, and average energy, danceability, and valence. Sort and filter by energy / vibe or release date to zero in on exactly the right records.
KeyTrack's smart recommendations don't just throw similar artists at you β they're ranked by harmonic and BPM compatibility to your anchored key (or seeded randomly when you're exploring), so suggestions are tracks you could genuinely drop next.
The Set Builder lets you assemble an ordered set pulling from any of your playlists. As you sequence, KeyTrack validates each key + BPM transition and flags the rough cuts before you ever hear them. Save, load, and rename named sets so your prep carries between sessions.
Listen to both sources in the browser from the same bottom bar: Spotify tracks through the Web Playback SDK, and SoundCloud through its native waveform player (with its own volume control). A slim Now Playing is always in reach, showing the current track's key, BPM, and β for SoundCloud β its chord loop, orange-badged so you always know the source. The app also ships with a light/dark theme, a desktop sidebar that becomes a mobile hamburger drawer, animated crate loaders, and an in-app changelog.
Artwork Explorer turns every cover in your library into a visual reference board β for when you're making art for your own release and want to see what the music you love actually looks like. Each playlist becomes an album of its covers, or flatten every playlist at once and browse the lot. Open any piece full-view to read its colour palette and copy the hex codes straight out.
Search it like you'd describe it. KeyTrack analyzes each cover's colour and mood β dark, neon, pastel, monochrome, minimal, high-contrast β right in your browser, for free. Add a Gemini key and it also reads what's actually in the picture, so you can search "foggy neon city at night", filter by genre, or point at a cover you love and ask for more like this. Collect the keepers onto mood boards, one per release.
It costs nothing extra to run: covers come from the crate cache the library already keeps, and each unique cover is analyzed once and remembered.
Any work that I did with Claude will have a π€ Generated with Claude Code footer on its pull requests. All the features on this app from a product perspective are my own ideas or ideas that I have evolved from using similar DJ and music software, or pain points that I wanted to solve for myself as a DJ and artist.
There are two ways to run locally. Option A needs no Spotify credentials of your own and is the quickest way to get a working login; Option B runs the whole stack on your machine.
- Node.js v16+
- Spotify Premium (required by the Web Playback SDK)
- For Option B only: a Spotify Developer account
The OAuth round-trip runs against the deployed Heroku backend using its
registered redirect URI, so you need no SPOTIFY_ID/SPOTIFY_SECRET locally
and no extra redirect URI in the Spotify dashboard. Only the final hop comes
back to your dev server.
cd client
cp .env.example .env.local # then uncomment REACT_APP_BACKEND
npm install # first time only
npm start # serves on http://localhost:3000.env.local:
REACT_APP_BACKEND=https://key-track2.herokuapp.com
The frontend asks the backend to return the tokens to its own origin
(?return_to=http://localhost:3000). The backend honours this only for origins
in the RETURN_TARGETS allowlist in local-server/index.js
β tokens ride on that redirect, so an arbitrary origin would be an open redirect
that leaks them. To use a different port or host, add it to that allowlist and
redeploy the backend.
βΉοΈ CRA only reads
.env.localat startup β restartnpm startafter editing it.
At the Spotify Developer Dashboard, create an app and add this Redirect URI:
http://127.0.0.1:8888/callback
β οΈ Spotify rejectshttp://localhostas an "insecure" redirect β use127.0.0.1.
Note your Client ID and Client Secret.
cd local-server
cp .env.example .env # then fill in SPOTIFY_ID and SPOTIFY_SECRET
npm install # first time only
npm start # serves on http://127.0.0.1:8888The server warns on startup and returns an explicit spotify_not_configured
error (instead of an opaque 401 later) if those two values are missing.
In a new terminal, with no REACT_APP_BACKEND set (the default targets
http://127.0.0.1:8888):
cd client
npm install # first time only
npm start # serves on http://localhost:3000- Open
http://localhost:3000 - Click Log in with Spotify (the Key Calculator works without logging in)
- Open your Library, dig through crates by key / BPM / energy, build sets, and play tracks in-browser
- Open Artwork Explorer to browse your covers as a visual reference board
Artwork Explorer's colour/mood analysis runs free in the browser with no setup. To also search covers by content ("foggy neon city at night") and use find-similar, add a Gemini API key to the backend:
# local-server/.env
GEMINI_API_KEY=your_gemini_api_keyIn production set it as a Heroku config var. The key stays server-side β it must never reach the React bundle, which is world-readable. Each unique cover is analyzed once and cached permanently, so the cost is one-time.
Mind the rate limit. Gemini's free tier allows 15 requests per minute,
so a large library takes hours. The backend paces every call to stay under
GEMINI_RPM (default 15) rather than collecting 429s β raise it once billing is
enabled:
GEMINI_RPM=15 # free tier; raise to match your paid quotaFrontend β React (Create React App), Material-UI v4, spotify-web-api-js, react-spotify-web-playback, Firebase / Firestore (saved sets + crate metadata), deployed to Netlify.
Backend β Node.js + Express handling the Spotify OAuth flow, deployed to Heroku (auto-deploys on merge to master).
Frontend (Netlify) β continuous deployment from master via client/netlify.toml. Manual deploy:
cd client && npm run build && netlify deploy --prod # publish dir: ./buildBackend (Heroku) β auto-deploys when master updates. For production set SPOTIFY_ID, SPOTIFY_SECRET, and NODE_ENV=production, and register the production https://<your-app>/callback redirect URI in the Spotify dashboard.
MIT β see LICENSE. Use it, fork it, mix with it.
Tam Nguyen Β· built with Spotify π΅, Cursor β‘, and Claude Code π€








