Track Spotify songs that disappear from your Liked Songs or playlists, preserve the history, and get weekly alerts.
Live app: https://fadeless.app
Spotify can remove tracks silently when rights change or songs are re-uploaded under new IDs. Fadeless gives users visibility into those removals by taking snapshots, diffing them over time, and keeping an archive.
- Authenticates users with Spotify OAuth 2.0 + PKCE (no passwords stored)
- Scans Liked Songs and monitored playlists for removals
- Stores append-only snapshots and removal events in PostgreSQL
- Shows weekly and all-time removal history in the dashboard
- Supports playlist-level monitoring toggles (up to 5 playlists per user)
- Sends weekly digest emails (Resend) or in-app notification badges
- Exports removal history as JSON or CSV
- Supports user data deletion from the settings page
- Frontend: Next.js App Router + React + TypeScript + Tailwind
- Backend: Route Handlers + Server Actions + modular service layer
- Database: PostgreSQL + Prisma
- Jobs:
- On-demand scan route:
POST /api/jobs/scan - Netlify background scan worker:
/.netlify/functions/daily-scan - Weekly digest route:
POST /api/jobs/send-weekly-digest
- On-demand scan route:
- Scheduling:
.github/workflows/daily-scan.ymltriggers Netlify scan function every 6 hours.github/workflows/weekly-digest.ymltriggers weekly digest every Monday
- Next.js 16 (App Router)
- React 19
- TypeScript
- Tailwind CSS
- shadcn/ui primitives (Radix)
- Prisma ORM
- PostgreSQL
- Spotify Web API
- Resend (weekly digest email delivery)
- OAuth PKCE for Spotify authorization
- Encrypted access and refresh tokens at rest (AES-256-GCM)
- Signed, server-managed sessions
- Least-privilege Spotify scopes (read-focused)
- Basic API/job rate limiting
- User-scoped data isolation
- One-click history deletion
- Semantic HTML and accessible component patterns
- Keyboard navigation support
- Visible focus states
- Contrast-aware, Spotify-inspired UI choices
- Current release focuses on removal detection by exact Spotify track ID.
- Spotify app allowlist behavior still applies while the Spotify app remains in development mode
src/app: routes, API handlers, server actionssrc/components/auth: auth and account menu UIsrc/components/dashboard: dashboard-level UI sectionssrc/components/library: library browser panel and subviewssrc/components/landing: logged-out landing experiencesrc/components/navigation: shared navigation componentssrc/components/onboarding: onboarding dialog flowsrc/components/scan: manual scan form/button/status UIsrc/components/settings: settings forms and controlssrc/lib: business logic (auth, Spotify client/service, jobs, repositories, security, notifications)src/ui: shared primitive UI componentsprisma: schema and migrationsnetlify/functions: Netlify scheduled/background scan handlers
- Node.js 20+
- PostgreSQL
- Spotify developer app credentials
- Install dependencies:
npm ci
- Create
.env.local(see env table below). - Apply Prisma migrations:
npx prisma migrate dev
- Start the app:
npm run dev
- Open
http://localhost:3000.
Create .env.local with:
| Key | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
DIRECT_URL |
No | Optional direct PostgreSQL URL for Prisma |
SPOTIFY_CLIENT_ID |
Yes | Spotify app client id |
SPOTIFY_CLIENT_SECRET |
Yes | Spotify app client secret |
SPOTIFY_REDIRECT_URI |
Yes | OAuth callback URL (for local: http://localhost:3000/api/auth/callback) |
SPOTIFY_SCOPES |
No | Optional scope override |
ENCRYPTION_SECRET |
Yes | 32+ byte secret for token encryption |
SESSION_SECRET |
Yes | 32+ byte secret for session signing |
NEXT_PUBLIC_APP_URL |
Yes | Public app URL (http://localhost:3000 locally) |
RESEND_API_KEY |
No | Resend key for weekly email digests |
EMAIL_FROM |
No | Verified sender address for digest emails |
GET /api/auth/loginGET /api/auth/callbackPOST /api/auth/logoutPOST /api/jobs/scanPOST /api/jobs/baseline-likedPOST /api/jobs/send-weekly-digestGET /api/notifications/badgesGET /api/exports/removals?format=json|csv
- Lint:
npm run lint - Typecheck:
npm run typecheck - Tests:
npm test
MIT. See LICENSE.
Live and actively maintained portfolio project.




