exportify: turning a Spotify playlist into a CSV and a taste profile
Export Spotify playlists using the Web API. Analyze them in the Jupyter notebook.
At a glance
- What is it?
- exportify is a browser based tool that reads your Spotify playlists through the Spotify Web API and exports the track metadata as CSV, with a Jupyter notebook that plots the result. It suits a listener who wants to keep a copy of their playlist data or look at their listening habits numerically, and it is not a downloader, since it exports metadata rather than audio.
- Who is it for?
- exportify fits a listener who wants their own playlist metadata in a spreadsheet they can keep or analyse, and it does not fit anyone expecting audio files, since the export is track metadata and the audio features come from Spotify's own analysis of each track.
- 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 5 days ago.
- What is it written in?
- Mainly Jupyter Notebook, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What gets exported is metadata, not music
exportify does one thing: it takes the contents of a Spotify playlist and writes it out as a CSV file that you keep. The README describes the project as exporting Spotify playlist metadata for analysis or safekeeping, and the live tool is at exportify.net.
The export format is a flat CSV with a long column list, and reading that list tells you what the tool is really working with. Alongside the obvious identity fields such as Track URI, ISRC, Track Name, Album Name, Artist Name(s), Release Date, Duration (ms), Popularity, Explicit, Added By and Added At, there are Genres and Record Label, and then a block of the audio features that Spotify computes for every track: Danceability, Energy, Key, Loudness, Mode, Speechiness, Acousticness, Instrumentalness, Liveness, Valence, Tempo and Time Signature.
So the file is two things at once. It is an archive of the playlist as it looked, which is the safekeeping half, and it is a table of numeric descriptors of each track, which is the analysis half. The audio itself is not part of the export, and that is worth stating plainly at the start, because the name of the project invites a wrong assumption.
The Web API client lives in exportify.js and the page in index.html
The development notes in the README describe the architecture plainly. Most of the logic that talks to the Spotify Web API is written in JavaScript in exportify.js, and the author says there are many detailed code comments and that the structure was kept as rational as possible. The webpage skin and a few action bindings are defined in index.html.
That split is the interesting part of the design, and it explains why the tool runs in a browser rather than as a server. The repository topics list javascript and javascript-promise alongside spotify-web-api, and the promise based style is the natural way to sequence the many API calls a playlist export needs, since each track brings follow-up requests for its audio features and its artist. Doing that in the browser keeps the user credentials and the API traffic on the user's own machine, with no server in the middle.
The repository also contains FileSaver.js, which is how the browser writes the finished CSV to disk, plus style.css, a favicon, and images including screenshot.png, saved_albums.png and liked_songs.jpeg that appear in the documentation. A deploy workflow badge points to a GitHub Actions workflow named deploy.yml, which is how a static site of this shape gets published to GitHub Pages, and the repository topics list includes github-pages-website.
A local web server is all the development setup requires
The README gives a development loop that is short enough to state in full. To experiment with changes you run a local web server from the repository directory, and the example given uses Python.
python3 -m http.serverThen you open the loopback address the server prints, and the JavaScript is invoked by interacting with that locally served page. The project uses no build step, no bundler and no package manager for the browser code, which is consistent with it being plain JavaScript served as static files.
The second half of the loop is the data science side. The analysis is written in Python inside taste_analysis.ipynb, and the README says you can run it with a Jupyter notebook server, starting it with the command python3 -m notebook and then navigating to the notebook address the server prints. The data side has real dependencies, and requirements.txt lists them.
matplotlib
pandas
scipy
seaborn
scikit-learn
numpyThe presence of scipy and scikit-learn is what makes the similarity plot in the notebook possible, and seaborn covers the distribution charts.
The two halves are deliberately separate. The browser produces a CSV, the notebook consumes it, and the only interface between them is that file. That means you can take the CSV elsewhere and leave the notebook out of the picture entirely if you only want the export.
The notebook turns a track list into a listening profile
The analysis notebook is where the project becomes interesting beyond data collection. The README lists the plots it produces: most common artists, most common genres, release date distribution, popularity distribution, distributions of Acousticness and Valence and the other features, time signatures and keys, and all songs plotted in two dimensions to indicate relative similarities.
That last plot is the one worth dwelling on, because it is the reason the requirements file includes scikit-learn. A two dimensional embedding of a playlist puts tracks that sound alike near each other, so a listener can see at a glance whether a playlist is one coherent genre or a scatter of unrelated moods, and can spot the outlier tracks that do not belong.
The distributional plots work the same way in a different register. A histogram of release dates says how recent a playlist is, a histogram of popularity says whether the tracks are famous or obscure, and a breakdown by key and time signature says something about the production style. Since every one of those columns comes from Spotify's own feature analysis rather than from anything computed here, the notebook is really a way of reading a table Spotify already produced.
The project is described as analyzing playlists in a Jupyter notebook, and the two deployment paths are given: run the notebook yourself from the repository, or launch it in Binder through the badge in the README, which builds an environment from the repository on demand.
The export is only as complete as the API returns
There is a limit to this approach that follows directly from the design, and it is worth naming before anyone plans a large archive around the tool.
Everything comes from the Spotify Web API, so the output inherits the API's coverage rules, its rate limits, and its own idea of what a playlist contains. Added By and Added At are per playlist and per account, and the presence of a liked_songs.jpeg screenshot in the repository suggests the liked songs view is treated as a playlist-like target. Features such as Genres and Record Label are documented by Spotify at the album level, so a track entry in a CSV can be carrying data that describes its release rather than the track itself.
The deeper constraint is the one the project does not discuss. The README says nothing about how the API credentials are obtained, how long they last, or what happens when Spotify changes its authorisation flow, and that is a real gap for anyone planning to use the tool for years rather than once. There is also no description of a refresh or a sync, so a CSV produced today is a snapshot rather than a growing archive, and keeping a historical record means running the export again and storing the new file alongside the old ones.
The MIT licence covers the code, and the tool is published as a static site through GitHub Pages, so there is no server component to operate. What it does need is a Spotify account and the Web API credentials to go with it, and the README does not walk through obtaining those.
Against a manual copy and paste, and against a fuller database
The obvious alternative to exportify is manual effort. The Spotify app or web player can show a playlist, and a user can copy track names into a spreadsheet, or export the playlist to a file the service offers and clean it up. That approach needs no API credentials and no code, and for a one-off list of twenty songs it is faster than anything else here.
It also stops at names. A manual copy gives you titles and artists and nothing else: no ISRC, no release date, no popularity, no audio features, nothing that can be aggregated. The difference between that and exportify is the difference between a list and a table, and the table is what makes the notebook possible at all.
The other alternative is a fuller data platform. A user who wants continuous, historical, multi-playlist data with scheduled collection and a database behind it needs a proper integration, and a tool like this does not compete with that. Exportify is a single page that runs in a browser, exports one playlist at a time, and hands you a file. It is the right size for someone who wants to look at one playlist properly and then move on.
The difference in approach between the two is worth keeping in mind for a larger project: exportify is client side, so the credentials and the traffic stay with the user, and the only artifact is the CSV. That simplicity is the feature, and also the reason it does not scale to a collection pipeline.
Editorial conclusion
exportify fits a listener who wants their own playlist metadata in a spreadsheet they can keep or analyse, and it does not fit anyone expecting audio files, since the export is track metadata and the audio features come from Spotify's own analysis of each track. Before relying on it, export one playlist and check the row count against the track count Spotify shows you, because the tool reads the API rather than the playlist page, and note that the analysis notebook needs the local Python stack listed in requirements.txt rather than the browser alone.
Frequently asked questions
What does exportify export from a Spotify playlist?
It exports track metadata as CSV, including Track URI, ISRC, Track Name, Album Name, Artist Name(s), Release Date, Duration (ms), Popularity, Explicit, Added By, Added At, Genres, Record Label, and the audio features such as Danceability, Energy, Key, Loudness, Valence and Tempo. It does not export the audio itself.
How do I run the exportify development server locally?
Run a local web server from the repository directory with python3 -m http.server, then open the address it prints and interact with the served page. The data analysis part runs separately with python3 -m notebook, which serves the taste_analysis.ipynb notebook.
What Python packages does the exportify notebook need?
The requirements.txt file lists matplotlib, pandas, scipy, seaborn, scikit-learn and numpy. The browser side of the project needs no Python packages, since the Spotify Web API logic is JavaScript in exportify.js and the page is defined in index.html.
Can I analyze an exported exportify CSV without the notebook?
Yes. The notebook consumes the CSV file, and the export is the only artifact the browser side produces, so any tool that reads CSV can work with the same file. The notebook is one option rather than a requirement.
Official sources
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.
[](https://hysenlabs.com/projects/pavelkomarov-exportify)Was this useful?