CLI tool
sigma67/spotify_to_ytmusic avatar
sigma67/spotify_to_ytmusic

spotify_to_ytmusic rebuilds a Spotify playlist inside YouTube Music

Clone a Spotify playlist to YouTube Music

1,533 stars104 forksPythonMIT

At a glance

What is it?
spotify_to_ytmusic is a command line script that copies Spotify playlists into YouTube Music through spotipy and ytmusicapi, including liking the tracks and bulk transfers for a whole user. Two things will bite you: a Spotify Premium subscription is required, and the update subcommand empties the YouTube Music playlist before refilling it.
Who is it for?
Use it for a one-off migration off Spotify when you can accept that tracks which do not match in the YouTube Music catalogue end up in noresults_youtube.txt and have to be fixed by hand. Do not point the update subcommand at a playlist you have curated, because it deletes the entries first.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

It copies a playlist by searching for each track again

spotify_to_ytmusic is a command line script whose job is to clone a Spotify playlist into YouTube Music. The README lists what it covers: transfer a single Spotify playlist, like all the songs in a Spotify playlist, update a transferred playlist on YouTube Music, transfer all playlists for a Spotify user, like all songs from all playlists for a user, and remove playlists from YouTube Music.

The transfer itself is a two service problem. Spotify is read through spotipy, YouTube Music is written through ytmusicapi, and the script sits between them, resolving each Spotify track to a YouTube Music track and building the playlist from the results. The project does not claim to move audio. It moves the playlist shape, and it likes the tracks as a side effect, so the target playlist behaves like a playlist you subscribed to.

The audience is someone leaving Spotify, or someone who wants the same set of tracks in a YouTube Music account for a device that no longer has Spotify installed. It is a migration utility, not a library.

A Spotify Premium subscription decides whether the API answers

The README carries a warning that belongs at the top of any evaluation, because it decides whether the tool works at all for you.

Spotify Premium is required. Spotify restricts parts of its Web API for apps owned by accounts without an active Premium subscription. Without Premium, requests can fail with 403 Forbidden errors, which may break the create, update, all and liked commands. The project is explicit that the account which owns your developer app needs an active Premium subscription, and points at Spotify's Web API documentation for the current access rules.

That is an unusual dependency for a free, MIT licensed script. The tool is free, but the account on the Spotify side must be a paying one, and the restriction bites the commands that read playlists rather than the ones that only write to YouTube Music. A trial account that has expired is the classic way to hit it, and the symptom, a 403 with no obvious cause, does not point back at the subscription.

Setup writes a settings file that both APIs read

Credentials come from two developer consoles, which is the first piece of friction. The setup steps are: generate a new app at the Spotify developer dashboard, generate a new app by following the ytmusicapi OAuth setup instructions, and then run the setup command.

bash
pipx ensurepath
pipx install spotify_to_ytmusic
spotify_to_ytmusic setup

The setup command writes the credentials where the script can find them, and for backwards compatibility you can create your own file and pass it with --file settings.ini. Where that file lives is decided by platformdirs, one of the three runtime dependencies, so the settings follow the conventions of the operating system rather than the current directory.

There is a decision during setup that changes what the tool can reach. If you want to transfer private playlists from Spotify, which the documentation gives as the example of liked songs, you choose yes for oAuth authentication, otherwise you choose no. For oAuth you must set https://127.0.0.1 as the redirect URI for your app in the Spotify developer dashboard.

Tracks that do not match are written to noresults_youtube.txt

Running a transfer is one command with a playlist link:

bash
spotify_to_ytmusic create <spotifylink>

The script logs its progress and outputs the songs it could not find in YouTube Music to a file called noresults_youtube.txt. That file is the honest part of the tool. A Spotify track has a title, an artist and a set of recordings; YouTube Music has its own catalogue, and a match is only as good as the search that produced it. Some tracks will simply not be there under any name you would guess.

The consequence is that a transfer is not a finished playlist. It is a playlist plus a work list. The unmatched tracks have to be searched, corrected and added by hand, and the file is the record of what still needs attention.

For bulk work, the same mechanism scales up. The all subcommand transfers all public playlists of a given user, identified by the Spotify user ID, and the liked subcommand handles the liked tracks of the Spotify user, which is the private case and therefore requires oAuth.

The update subcommand empties the playlist before it refills it

This is the part to read twice before pointing the tool at a playlist you care about. The help text describes update as deleting all entries in the provided Google Play Music playlist and updating the playlist with entries from the Spotify playlist.

The wording is old, referring to the service as Google Play Music, which tells you how long this code path has been in place. The behaviour is the issue, not the naming. Update is not a merge and it is not a diff. It clears the destination playlist and then refills it from the Spotify source, so anything you had added to the YouTube Music copy by hand is gone in the process, and the refilled list contains only what the current Spotify side can be matched to.

The remove subcommand has the same flavour of bluntness in a different direction: it removes playlists matching a specified regular expression. A pattern that is broader than intended will take more playlists with it, so the expression deserves a look before you run it. The README does not document a dry run or a confirmation prompt for either command.

Bulk transfer and the liked songs command

Two subcommands cover everything beyond a single playlist, and they have different requirements.

bash
spotify_to_ytmusic all <spotifyuserid>
spotify_to_ytmusic liked

The all command exists for migration purposes and transfers all public playlists of a user, identified by the unique username, the Spotify user ID. It is the one to use when you are moving an account rather than a playlist.

The liked command handles the Spotify liked tracks, and the documentation is firm that you must use oAuth authentication for it. The flow is deliberately manual at the last step. The command opens a browser where you give access to your account, unless you have done that before, and then you are redirected to 127.0.0.1. You copy the link you were redirected to, which looks like 127.0.0.1/?code=..., and paste it to the command line. A loopback redirect is used because there is no server to receive a callback, so the code is handed back through the clipboard.

The subcommand list in the help output is setup, create, update, remove and all, with the liked command documented separately in the README. If a subcommand you expect from the prose is missing from your install, that mismatch is the reason.

pipx install, a git derived version and a small toolchain

Installation assumes Python 3.10 or later and pipx, and the documented sequence is pipx ensurepath, a new shell, and then pipx install spotify_to_ytmusic. The project is also published to PyPI under the name spotify_to_ytmusic, and the console script is declared in pyproject.toml as spotify_to_ytmusic = spotify_to_ytmusic.main:main.

Three runtime dependencies do the work: ytmusicapi at 1.11.0rc1 or later, spotipy at 2.25.0 or later, and platformdirs at 3.2 or later. The version number itself is not written into the project file, it is derived from the git history by setuptools_scm, and the repository carries a pdm.lock file, so a checkout has a lock file even though the build system is setuptools.

The development side is compact. Pytest runs with --verbose --cov --junitxml=junit.xml over the tests directory, ruff handles linting with a selected rule set, and mypy type checks the spotify_to_ytmusic package with a per module override that silences missing imports for spotipy.

On maintenance, the repository is not archived and the last push was on 2026-10-16. The tagged releases are older: 0.6.1 in January 2025, 0.7.0 in March 2025 and 0.8.0 in April 2025. The licence is MIT, and the classifiers cover Python 3.10 through 3.13.

Editorial conclusion

Use it for a one-off migration off Spotify when you can accept that tracks which do not match in the YouTube Music catalogue end up in noresults_youtube.txt and have to be fixed by hand. Do not point the update subcommand at a playlist you have curated, because it deletes the entries first. Before you start, confirm the Spotify account that owns your developer app has an active Premium subscription, and create the YouTube Music app through the ytmusicapi OAuth setup so the credentials file matches what spotify_to_ytmusic setup expects.

Frequently asked questions

How do I install spotify_to_ytmusic?

You need Python 3.10 or later and pipx. Run pipx ensurepath, open a new shell, then pipx install spotify_to_ytmusic, and finish with spotify_to_ytmusic setup to store the Spotify and YouTube Music credentials.

Why does spotify_to_ytmusic fail with a 403 Forbidden error?

Spotify restricts parts of its Web API for apps owned by accounts without an active Premium subscription, and those requests fail with 403 Forbidden, which can break the create, update, all and liked commands. The account that owns your developer app needs an active Premium subscription.

How do I transfer private playlists or liked songs from Spotify?

Choose yes for oAuth authentication during setup, and set https://127.0.0.1 as the redirect URI for your app in the Spotify developer dashboard. The liked command then opens a browser, and you paste the redirected link, which looks like 127.0.0.1/?code=..., back to the command line.

What happens to songs that cannot be found on YouTube Music?

The script logs its progress and writes the songs it could not find in YouTube Music to noresults_youtube.txt. Those tracks are not added to the new playlist and have to be found and added by hand.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sigma67/spotify_to_ytmusic on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sigma67-spotify-to-ytmusic.svg)](https://hysenlabs.com/projects/sigma67-spotify-to-ytmusic)

Was this useful?