2026-04-09 02:28:36 +02:00
2026-04-09 02:28:36 +02:00

NaviMigrate

Spotify -> Navidrome playlist transfer tool in Go.

What it does

  • Authenticates with Spotify using Authorization Code + PKCE (no client secret required).
  • Fetches one or more Spotify playlists by URL/URI/ID.
  • Searches for matching tracks in Navidrome using Subsonic search3.
  • Creates matching playlists in Navidrome and adds matched tracks.
  • Writes a JSON transfer report with unmatched tracks and errors.

Requirements

  • Go 1.22+
  • Spotify app client ID with redirect URI configured (default: http://127.0.0.1:8888/callback)
  • Navidrome URL, username, and password

Build

go build ./cmd/navimigrate

Usage

./navimigrate \
  --spotify-client-id "<spotify-client-id>" \
  --navidrome-url "https://music.lofitrek.com" \
  --navidrome-username "test_user" \
  --navidrome-password "test_user" \
  --playlist-url "https://open.spotify.com/playlist/16DZpOTLqZvdbqxEavLmWk"

Useful flags

  • --playlist-url "..." (repeatable): Spotify playlist URL/URI/ID
  • --dry-run: resolve matches only, do not create playlists or add tracks
  • --report transfer-report.json: report output path
  • --concurrency 4: concurrent track match workers
  • --spotify-manual-code=true|false: manual callback URL/code entry or local callback server

Navidrome self-test

Quick auth/search test without Spotify:

./navimigrate \
  --navidrome-url "https://music.lofitrek.com" \
  --navidrome-username "test_user" \
  --navidrome-password "test_user" \
  --navidrome-self-test

Write-path self-test (creates playlist, adds one track, then deletes playlist):

./navimigrate \
  --navidrome-url "https://music.lofitrek.com" \
  --navidrome-username "test_user" \
  --navidrome-password "test_user" \
  --navidrome-self-test \
  --navidrome-self-test-write

Environment variables

  • SPOTIFY_CLIENT_ID
  • SPOTIFY_REDIRECT_URI (optional)
  • SPOTIFY_SCOPES (optional)
  • NAVIMIGRATE_SPOTIFY_MANUAL_CODE (optional, defaults to true)
  • NAVIDROME_URL
  • NAVIDROME_USERNAME
  • NAVIDROME_PASSWORD
  • NAVIMIGRATE_DRY_RUN (optional)
  • NAVIMIGRATE_CONCURRENCY (optional)
  • NAVIMIGRATE_REPORT (optional)
  • NAVIMIGRATE_NAVIDROME_SELF_TEST (optional)
  • NAVIMIGRATE_NAVIDROME_SELF_TEST_WRITE (optional)
  • NAVIMIGRATE_NAVIDROME_SELF_TEST_QUERY (optional)
Description
No description provided
Readme 62 KiB
Languages
Go 100%