A cross-platform tray app that watches your Spotify Liked Songs and your own playlists, captures every track that has ever been in them, and tells you when Spotify silently removes one.
- Authenticates against your Spotify account with OAuth 2.0 + PKCE (no client secret, no server).
- Syncs Liked Songs and selected user playlists on a configurable schedule (default every 6 hours).
- Compares each Sync against the previous state and flags any track that disappears.
- Distinguishes Tombstones (Spotify-side removals, flagged immediately) from Vanished items (ambiguous, confirmed after a second consecutive Sync).
- Surfaces Lost tracks inline in the playlist view with a removed-icon and a filter to show "removed only".
- Stores everything in SQLite locally. Manual JSONL export when you want a portable backup.
- Track playlists you do not own (Discover Weekly, Release Radar, friends' playlists).
- Remember when a track was removed — the archive records that a Loss happened, not when.
- Cloud-sync between devices. Single-device, single-user tool.
- Restore tracks. The archive preserves enough metadata (title, artist, album) to manually re-find a Lost track on Spotify.
Tauri 2 + React + TypeScript + Tailwind, built with Bun and Vite+. SQLite via sqlx on the Rust side. Spotify access via rspotify. Full stack and rationale: docs/decisions.md.
Prerequisites: Bun, a Rust toolchain, and the Tauri system dependencies for your OS.
-
Create a Spotify app. Go to the Spotify Developer Dashboard, create an app, and add
http://127.0.0.1:4202/callbackas a Redirect URI. Copy the Client ID (this is a public PKCE client — there is no client secret). -
Provide the client id. The id comes from
SPOTIFY_ARCHIVIST_CLIENT_ID. Copy the example file and fill in your id:cp .env.example .env # edit .env and set SPOTIFY_ARCHIVIST_CLIENT_IDIn development the
.envat the project root is loaded automatically. -
Install and run.
bun install bun run tauri dev
At startup the app resolves the id in this order:
- The
SPOTIFY_ARCHIVIST_CLIENT_IDruntime environment variable (including the.envloaded in dev). This always wins, so you can override without rebuilding. - A value baked in at compile time from the same variable in the build environment. Release builds produced by CI inject it from a repository secret, so the shipped binaries run without the user setting anything.
- If neither is present the app panics with a clear message.
To build a release bundle locally, set the variable so it is baked in:
SPOTIFY_ARCHIVIST_CLIENT_ID=your_id bun run tauri buildCONTEXT.md— domain glossary.docs/decisions.md— frozen design decisions with links to source artefacts.docs/plan.md— phased implementation plan.docs/adr/— architecture decision records.
Spotify authentication uses OAuth 2.0 + PKCE, so there is no client secret to leak. Access and refresh tokens are stored in the OS keyring, never on disk in plaintext. To report a vulnerability, see SECURITY.md.
MIT.