Skip to content

About

Keepsake: private Spotify Liked Songs and playlist metadata backups. Browser capture, CSV/JSON/TXT/ZIP exports. MIT licensed.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Keepsake · Spotify Library Vault

Keep the songs. Take the list. A private, local app for saving your Spotify Liked Songs and playlist metadata as JSON, CSV, TXT, M3U8, or a ZIP containing all formats.

Open the app · Download the browser extension

New in 1.3: Best effort matching and bulk YouTube Music migration. Import CSV/TSV, common JSON, TXT, M3U/M3U8 or ZIP song lists. Choose Best effort for fewer reviews or Strict for closer recording matches. Best effort handles transliterated names, combined artist credits, remasters and small timing differences, with an option to prefer explicit recordings while allowing unlabeled fallbacks. Apply updated preferences to undecided songs in an existing job. One bulk action sets ready selections to liked, then searches and adds remaining automatic matches. It skips existing likes, verifies additions in batches, and saves resumable jobs. The optional Connect YouTube Music helper creates the local sign-in file for you using your signed-in browser, with no headers to copy. YouTube authentication stays in that local file; the hosted app never receives it. The prebuilt keepsake-migration.zip in Releases needs Python only; a source build also needs Node.js.

Why it exists

Your music library is worth keeping when a subscription ends or a catalogue changes. Keepsake saves the list you can still see, with track names, artists, albums, Spotify identifiers, displayed saved dates, durations, and explicit labels when available. It exports metadata, not audio. It cannot recover content Spotify has already removed from the interface or account-data export.

Archive import/export has no sign-up, analytics, token collection or API-key requirement. The UI uses local assets and system fonts. Imported archive data stays in memory until you download it. Optional YouTube Music migration uses a local companion, stores match jobs on disk, and requires local authentication to add likes. Search and review work without an authenticated account.

Capture your signed-in Spotify library

Chrome / Edge extension (recommended)

  1. Download keepsake-extension.zip from Releases and unzip it.
  2. Open chrome://extensions or edge://extensions, enable Developer mode, click Load unpacked, and choose the unzipped folder containing manifest.json.
  3. Open Liked Songs in the Spotify web player. Clear any search filter and choose List view. Include the Album and Date added columns to preserve them.
  4. Click the Keepsake extension icon, then Capture Spotify library in the app that opens.
  5. Keep the Spotify tab open and avoid changing its list or sort order. Keepsake scrolls the list, reads rendered rows, checks their numbered positions against the displayed total, and restores the original scroll position.
  6. Check the counts and download Backup ZIP. You can stop a running capture and save the partial result.

The same flow works for an open playlist or album track list. Capture additional collections individually. An album capture preserves the visible album tracks; it does not claim you liked every track. Extension access is granted to the tab where you click its icon; it has no persistent host permissions.

Bookmarklet (no extension installation)

Open the app and expand Get the browser helper. Drag Capture with Keepsake to your bookmarks bar. Open Spotify and click that bookmark. When scanning finishes, download the JSON from the panel, then import it into Keepsake.

Some browser or Spotify security settings block bookmarklets. Use the extension if nothing happens. The bookmarklet is entirely bundled; it does not load a remote script or call a hidden API.

Import official Spotify account data

Request Account data from Spotify’s privacy page. Once available, import YourLibrary.json, Playlist*.json, or the ZIP containing them. Keepsake also reopens its own JSON/ZIP backups. These files can preserve saved albums, artists, shows, and episodes in addition to tracks.

ZIP imports accept supported library JSON and music table/text/playlist files. Keepsake ZIPs use the master JSON to avoid importing duplicate format copies. Spotify account-profile, payment and history JSON is ignored. Listening history is not evidence that a song is liked. Input limits: 50 MB per input file, 100 MB expanded supported content per ZIP, 2,000 ZIP members. Files are never extracted to the filesystem. See the format guide for generic imports and column mapping.

Export formats

Format Use
JSON Master archive, exact metadata strings, collection order, saved items, capture status and warnings. Reimportable. Always contains the whole workspace.
CSV Selected collections with Track name, Artist name, Album name, ISRC (when supplied), Spotify URL/URI, saved date, displayed date, duration, explicit status, availability, collection, position, type, and YouTube ID/URL when supplied. UTF-8 BOM and RFC 4180 quoting.
TXT Readable numbered list with artist/title/album and Spotify links.
M3U8 Reference playlist with Spotify web links, not audio URLs; playback support depends on the receiving app.
ZIP Whole-library JSON plus selected-collection CSV, TXT, M3U8 and an explanatory README.

Search only changes the preview. CSV/TXT/M3U8 export all entries in the selected collection. CSV protects against formula injection by prefixing formula-like text with an apostrophe; JSON preserves the exact original string. Repeated track occurrences inside playlists remain separate, in order. Importing the same unchanged collection is idempotent; a changed collection is retained as a separate snapshot rather than overwriting the earlier one.

For migration, use a destination/import service that accepts CSV and map track, artist and album columns. These are generic portable exports, not a promise of compatibility with every migration service. Review matches: alternate editions and explicit/clean recordings may share similar names.

Completeness and limitations

  • All numbered rows captured means every row from 1 to the displayed total was read. It does not prove that Spotify exposes every song you ever saved. Check against Spotify’s headline count, especially if any filter is active.
  • Partial, stopped, unknown-total, and changing-list captures are marked. Do not sort, filter, edit the collection, or play music that reorders the list during a scan.
  • Virtualized lists, Spotify layout changes, loading errors, missing columns, or browser background throttling may interrupt extraction. You can still save partial results. Capture is limited to ten minutes per run.
  • Unavailable rows are retained when rendered. The app does not infer playability from the presence of a link, or infer “clean” from the absence of an explicit badge. Unknown values remain null/blank.
  • The web player does not expose ISRC or exact saved timestamps in its track table. Browser captures retain displayed date labels; they do not invent precision. Import files may provide more detail.
  • Importing a single saved-tracks API page marks it partial when pagination or totals indicate more rows. Keepsake itself does not call the Web API.
  • Browser capture works without a Premium API app. Spotify’s February 2026 developer migration guide describes the Premium requirement for developer-mode app owners. Spotify documents its account data separately.
  • This independent project is not affiliated with or endorsed by Spotify.

Run locally / develop

Requires Node.js 22 or newer.

npm ci
npm run check
npm run dev

Open http://127.0.0.1:4173. npm run build produces a static app and load-unpacked extension in dist/, and release/keepsake-extension.zip. No build tools are required to use a release. You may open dist/index.html directly for offline import/export, or serve dist/ from any static host. npm run dev serves the latest build; rebuild after source changes.

Source layout:

  • src/dom.js: pure DOM reader; semantic roles and stable test IDs, no generated Spotify CSS classes.
  • src/capture.js: bounded scrolling, progress, cancellation, coverage checks.
  • src/model.js: normalized portable schema and official-file import.
  • src/export.js: safe CSV, JSON, text, reference M3U8 and ZIP.
  • src/app.js: local UI, ZIP streaming and extension orchestration.
  • src/content.js, src/background.js, src/bookmarklet.js: browser entry points.
  • test/: synthetic tests; no private listening or account data.

GitHub Actions runs JavaScript and Python tests, builds the release ZIPs, and deploys GitHub Pages. Set Pages source to GitHub Actions. Install the Python companion from keepsake-migration.zip or the repository source following the migration guide. Keep personal exports under the ignored private-exports/ directory and credentials in .secrets/, or outside the repository. Never commit personal backups or authentication files.

Privacy and permissions

The Spotify extension requests only activeTab and scripting. It reads rendered track metadata in an isolated script context, without reading cookies, passwords, tokens, internal application stores or account profile fields. Archive import/export does not send your files to a service. Spotify itself loads its ordinary page content as the list scrolls.

The optional YouTube Music companion sends song queries and selected rating requests to YouTube Music using ytmusicapi. It uses your configured local auth file or the connection created by the separate YouTube Music helper. The helper observes session headers only from the music tab it opens during an explicit connection and sends them only to the loopback companion. Credentials stay out of reports and HTTP responses. Local job writes require the app's origin and a per-process CSRF token; the single connection endpoint accepts only the helper's exact origin plus a short-lived, one-time pairing token. The UI shows the destination before enabling additions. Personal backups and migration reports can reveal musical preferences; keep them private. See authentication and verification details.

License

MIT, copyright 2026 Artem Skulimovskiy.

About

Keepsake: private Spotify Liked Songs and playlist metadata backups. Browser capture, CSV/JSON/TXT/ZIP exports. MIT licensed.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages