Discover how your music taste evolved over the years.
Analyze your Spotify library, explore genre trends, compare tastes with friends, and share your musical journey.
- Interactive stacked area chart showing your genre distribution year by year
- Click any year to see detailed breakdown: top artists, genre percentages, first & last liked song
- Drill down into any genre to see all songs tagged with it
- Cosine similarity algorithm compares your genre profile with other users
- Combined scoring: 60% liked songs + 40% playlist overlap
- Filter by genre, sort by match percentage, set minimum threshold
- Full playlist sync with genre distribution per playlist
- Compatibility score showing how each playlist matches your overall taste
- Community playlists with genre filters and sorting
- Community stats: total songs, artists, users, time span
- Top artists with song lists and "liked by" indicators
- Genre breakdown across all users
- Community playlists with genre filters
- Generate shareable cards with your stats, top genres, and timeline
- Multiple formats: square, wide, story
- Download as image or share via Web Share API
- Bypass Spotify's 5-user development mode limit
- Upload your Spotify GDPR data export (ZIP)
- Full analysis pipeline: track details, genre enrichment, timeline computation
| Layer | Technology |
|---|---|
| Frontend | React 19 + Vite + Recharts |
| Backend | Node.js + Express |
| Database | Supabase (PostgreSQL) |
| Genre Enrichment | Spotify API + Last.fm + MusicBrainz |
| Auth | Spotify OAuth 2.0 (PKCE) |
| Deployment | Render |
Client (React SPA) Server (Express)
├── Hash-based routing ├── OAuth + PKCE auth
├── SSE for sync progress ├── Rate-limited API pipeline
├── html2canvas for sharing ├── Multi-source genre enrichment
└── i18n (EN/TR) │ ├── Spotify → genres
│ ├── Last.fm → top tags
│ └── MusicBrainz → fallback
├── Cosine similarity matching
├── Incremental sync (snapshot_id)
└── Client credentials for uploads
- Node.js 18+
- Spotify Developer app
- Last.fm API key
- Supabase project (free tier works)
1. Clone and install
git clone https://github.com/user/soundshift.git
cd soundshift
npm install
cd client && npm install && cd ..2. Database
Run supabase-schema.sql in the Supabase SQL Editor.
3. Spotify Dashboard
Create an app at developer.spotify.com.
Add redirect URI: http://127.0.0.1:3001/auth/callback
4. Environment
cp .env.example .envSPOTIFY_CLIENT_ID=your_client_id
SPOTIFY_SECRET_KEY=your_client_secret
LASTFM_API_KEY=your_lastfm_key
REDIRECT_URI=http://127.0.0.1:3001/auth/callback
FRONTEND_URL=http://127.0.0.1:5173
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key5. Run
npm run devOpen http://127.0.0.1:5173
- Push to GitHub
- render.com → New Web Service → connect repo
render.yamlauto-detected- Add environment variables with production URLs
- Add production redirect URI to Spotify Dashboard
1. Fetch liked songs (paginated, incremental via last_added_at)
2. Fetch playlists + tracks (skip unchanged via snapshot_id)
3. Enrich artist genres:
└── Spotify API → Last.fm tags → MusicBrainz fallback
4. Compute timeline (liked songs + playlist tracks, deduplicated)
5. Store timeline JSON in user record
Each artist goes through a 3-tier pipeline:
- Spotify — Artist genres from Spotify's catalog
- Last.fm — Top tags with weighted scoring (min count: 10)
- MusicBrainz — Community-driven tags as final fallback
Tags are normalized to macro genres (Pop, Rock, Hip-Hop, Electronic, etc.) via a curated mapping.
similarity = 0.6 * cosine(liked_genres_A, liked_genres_B)
+ 0.4 * avg_cosine(playlists_A, playlists_B)
Falls back to 100% liked-songs similarity if either user has no playlists.
Supports English and Turkish. Language switch available on all pages.
MIT



