Skip to content

Repository files navigation

Playlist Transfer

Move playlists freely between Spotify, TIDAL, and YouTube Music.

Connect two services, pick a playlist, and it gets recreated on the other service. Matching uses ISRC codes where both services support them (Spotify ↔ TIDAL is near-perfect) and scored fuzzy search (title + artist + duration) otherwise. Tracks that can't be matched are listed at the end so you can add them by hand.

  • No database, no server-side storage — OAuth tokens live in encrypted, httpOnly cookies in your own browser.
  • Built with Next.js (App Router) + TypeScript + Tailwind. Deploys to Vercel as-is.

Setup

npm install
cp .env.example .env.local   # then fill it in, see below
npm run dev                  # http://localhost:3000

SESSION_SECRET can be any long random string: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

You need to register a (free) developer app with each service you want to use. A service with missing credentials just shows as "Not configured" in the UI — the others still work.

Spotify

  1. Go to the Spotify Developer DashboardCreate app.
  2. Redirect URI: http://localhost:3000/api/auth/spotify/callback (add your Vercel URL variant too when deploying: https://<app>.vercel.app/api/auth/spotify/callback).
  3. Select Web API. Copy the Client ID and Client Secret into .env.local.
  4. Dev-mode apps only allow allowlisted users: add each user's email under User Management (up to 25).

TIDAL

  1. Go to the TIDAL Developer Portal and create an app.
  2. Redirect URI: http://localhost:3000/api/auth/tidal/callback (+ Vercel variant).
  3. Copy the Client ID and Client Secret into .env.local.
  4. The app requests the scopes user.read playlists.read playlists.write — make sure they're enabled for your app if the portal asks.

YouTube Music (via YouTube Data API)

YouTube Music has no public API of its own; playlists are shared with YouTube, so this app uses the YouTube Data API v3.

  1. In Google Cloud Console, create a project and enable YouTube Data API v3 (APIs & Services → Library).
  2. Configure the OAuth consent screen (External). While the app is in Testing mode, add yourself and any friends as Test users (up to 100).
  3. Create an OAuth client ID (type: Web application) with redirect URI http://localhost:3000/api/auth/youtube/callback (+ Vercel variant).
  4. Copy the Client ID and Client Secret into .env.local.

Quota warning: the free YouTube quota is 10,000 units/day and matching one track costs a 100-unit search (plus 50 to insert). Transfers into YouTube Music therefore stop after roughly 60 tracks/day — the app detects this, keeps what was transferred, and tells you to re-run the next day. Transfers out of YouTube are cheap and effectively unlimited. You can request a quota increase in Google Cloud Console if you need more.

Apple Music?

Not supported: Apple requires a paid Apple Developer Program membership ($99/year) to issue MusicKit tokens.

Deploying to Vercel

  1. Push this repo to GitHub and import it in Vercel.
  2. Set all the env vars from .env.local in the Vercel project settings, with NEXT_PUBLIC_BASE_URL=https://<your-app>.vercel.app.
  3. Add the https://<your-app>.vercel.app/api/auth/<provider>/callback redirect URIs to each developer app (Spotify, TIDAL, Google).

Anyone you've allowlisted (Spotify User Management / Google Test users) can then use the site. Opening it to the general public requires each platform's app review process.

How it works

app/api/auth/[provider]/…       OAuth start + callback + logout (PKCE, state check)
app/api/[provider]/playlists    list / create playlists
app/api/[provider]/…/tracks     read source tracks / add matched tracks
app/api/[provider]/match        match a batch of tracks against the destination
lib/providers/{spotify,tidal,youtube}.ts   one adapter per service
lib/match.ts                    normalization + scoring (ISRC first, fuzzy fallback)
hooks/useTransfer.ts            client-side transfer loop with live progress

The transfer runs in your browser as a series of small API calls (batch match → create → batch add), so long playlists aren't limited by serverless timeouts, and progress is shown per track.

About

Transfer playlists between Spotify, TIDAL, and YouTube Music - ISRC-based track matching, no database, deploys to Vercel

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages