Visualize and understand how you listen to music, without sharing your data.
The same old song? Late at night? Only in summer? Tracksy helps you answer these questions.
Tracksy is a privacy-first music streaming data visualization tool. All processing happens in your browser. Your data never leaves your device.
- π΅ Supports Spotify, Deezer, and any source via custom CSV
- π¦ Powered by DuckDB WASM: SQL in the browser, zero server
- π No account. No upload. No tracking.
You can skip this step and use the demo button on the home page to explore with pre-generated data.
Or bring your own data:
Spotify
- Request your data on your Spotify account
- Select "Extended streaming history"
- Click "Request data"
- Confirm via the email from Spotify
- Wait a few days
- Download the
.zipfile from the email
Deezer
- Request your data on your Deezer account
- Go to "Account settings"
- Scroll to "My personal data"
- Click "Request my data"
- Confirm by entering the code sent by email
- Wait a few days
- Download the
.xlsxfile from the email
Apple Music (experimental)
[!IMPORTANT] Apple Music support is experimental. The export format has significant limitations: artist name is not included in the data, which means artist-based charts will not populate. Some data quality issues may affect visualizations. Use at your own discretion.
- Sign in at privacy.apple.com and request a copy of your data.
- Click "Request a copy of your data"
- Select "Apple Media Services information" in the data categories
- Submit the request
- Wait a few days
- Download and extract the ZIP you receive by email
- Inside the archive, navigate to
Apple Music Activity/and findApple Music Play Activity.csv. - If the data is in a nested ZIP (e.g.
Apple_Media_Services.zip), upload the outer ZIP directly, Tracksy extracts it automatically.
JellyFin (experimental)
Requires the Playback Reporting plugin.
- In JellyFin, go to "Dashboard" > "Plugins" and install "Playback Reporting" if not already installed
- After some listening activity has been recorded, go to "Dashboard" > "Playback Report"
- Click "Export as CSV" to download
playback_report.csv
[!IMPORTANT] Artist and album names are not included in the plugin export. Charts based on artist or album will not be populated for JellyFin data.
Any other source
Tracksy accepts data from any source as long as you format it as a CSV with the following columns:
| Column | Type | Description | Example |
|---|---|---|---|
ts |
ISO 8601 UTC string | Start of play | 2024-03-15T14:30:00.000Z |
track_name |
string | Song title | Le vent se lève |
artist_name |
string | Artist (empty string if unknown) | Veridis Project |
album_name |
string | Album (empty string if unknown) | Voir le soleil |
ms_played |
integer β₯ 0 | Milliseconds played | 213000 |
track_uri |
string | Stable identifier (any unique string) | custom:veridis-project:le-vent-se-leve |
platform |
string | Source label | tidal |
Save the file as tracksy-custom.csv (exact name required) and upload it to Tracksy.
[!NOTE]
Records with
ms_played < 30000(less than 30 seconds) are filtered automatically.Use any stable string for
track_uri-custom:{artist}:{title}works fine.
ts,track_name,artist_name,album_name,ms_played,track_uri,platform
2024-03-15T14:30:00.000Z,Le vent se lève,Veridis Project,Voir le soleil,213000,custom:veridis-project:le-vent-se-leve,tidal
2024-03-15T14:33:53.000Z,Veridis Quo,Daft Punk,Discovery,243000,custom:daft-punk:veridis-quo,tidal
2024-03-15T14:38:06.000Z,my dey,Zubi,Dear Z,120000,custom:zubi:my-dey,tidalWorks with Excel, Google Sheets, LibreOffice Calc, or any equivalent.
- Open your export file in your spreadsheet editor.
- Rename each column header to match the required names:
ts,track_name,artist_name,album_name,ms_played,track_uri,platform. - Make sure
tsis formatted as ISO 8601 UTC (e.g.2024-03-15T14:30:00.000Z). If it is a date/time cell, format it as plain text first. - If your source has no unique track ID, add a
track_uricolumn with a formula like="custom:"&[artist column]&":"&[title column]. - Delete rows where the play duration is under 30 seconds (30 000 ms).
- Export as CSV with UTF-8 encoding.
- Rename the saved file to
tracksy-custom.csv.
If your source data is already in CSV or JSON, DuckDB CLI can reshape it in one query:
COPY (
SELECT
your_timestamp_col AS ts,
your_title_col AS track_name,
your_artist_col AS artist_name,
your_album_col AS album_name,
your_duration_ms_col AS ms_played,
'custom:' || your_artist_col || ':' || your_title_col AS track_uri,
'my-source' AS platform
FROM read_csv('your-export.csv', header = true)
WHERE your_duration_ms_col >= 30000
) TO 'tracksy-custom.csv' (HEADER, DELIMITER ',');Replace read_csv with read_json, read_xlsx or other depending on your source.
Go to Tracksy and upload your file, or hit the demo button.
Your data stays local. Nothing is sent anywhere. You can also self-host Tracksy.
Once uploaded, explore your listening habits across four views:
| View | Description |
|---|---|
| β¨ Simple | Curated and guided overview of your listening data |
| π¬ Lab | Experimental insights and advanced visualizations |
| π¬ Chat | Conversational exploration using a built-in LLM |
| β¨οΈ Query | Direct SQL-based exploration of the dataset |
/
βββ app/ # Astro + React frontend (DuckDB WASM)
βββ blog/ # Hugo static blog (ADRs and technical notes)
βββ e2e/ # Playwright end-to-end tests
βββ synthetic-datasets/ # Python scripts for generating test data
| Directory | Description |
|---|---|
app/ |
Frontend. DuckDB WASM processes data client-side; nothing reaches a server. |
blog/ |
Static blog with architectural decision records. |
e2e/ |
End-to-end test suite built with Playwright. |
synthetic-datasets/ |
Generates synthetic Spotify/Deezer/Apple Music/Custom streaming histories for testing. |
moon setup # download Node.js, Python, and dependencies
moon run app:dev # start the dev serverMore details in the CONTRIBUTING.md development section.
Tracksy is under active development. On the horizon:
- More visualizations and a simplified view for non-technical users
- Support for additional data sources (Funkwhale, etc.)
See open issues for the full list.
Contributions are welcome! Open an issue or a pull request (read CONTRIBUTING.md first).
If you would like to be added to or removed from the contributors list, feel free to open an issue or a PR.
Tarek Touati |
Benjamin |
noancloarec |
Jean-Phi Baconnais |
Arthur Lutz |
