Skip to content
← All work

Backtrack

Your Spotify history, turned into games and a library. Import the export Spotify sends you and play against your own listening, or open a library that charts eight years by year, month, and hour and ranks every track, artist, and album. Nothing leaves your phone.

Backtrack is a working name.

Role
Product, design, iOS
Platform
iOS
Stack
Swift 6, SwiftUI, SQLite
Status
In development
Backtrack's library, all time: 13,622 hours over 264,358 plays, with hours by year and by hour of the day
The Timeline game's reveal in Backtrack: a close guess for a Jeff Buckley track, the real year, and listening by year

The problem

Spotify will email you eight years of listening as a zip, then leave you with a pile of JSON.

That export is the most complete record anyone has of what you actually listened to, and almost nobody can open it. The yearly recap picks a few numbers for you and moves on. The rest sits in a file.

Backtrack reads the file on the phone and does two things with it. It turns the history into games you play against yourself, and it turns it into a library you can wander through.

What we built

Three games and a library, all drawn from the same local index, with no account, no network, and no ads.

Mystery track
One track a day to guess from six clues in six guesses. The day and a fingerprint of your library pick it, so the same person gets the same track on the same day, with no repeats until the pool is used up.
Higher or lower
Two songs or two artists. Pick the one you played more.
Timeline
Guess the year you played a track most, then see the real spread. Close counts for a point, and the bars show the truth.
Library
All time or any single year: listening by year, month, and hour of the day, and every track, artist, and album ranked, with search that keeps each row’s true rank.
Pages
Every track, artist, and album opens to its rank, headline numbers, charts, and links between the three.
Two exports, joined
Spotify’s full export can take a month to arrive, and the quicker account download covers only the last year. Backtrack reads both and stitches the newer months onto the full record without counting anything twice.

Decisions that matter

Nothing leaves the phone.

The export carries IP addresses alongside every play. The parser never decodes that field, so it never reaches the database. There are no analytics and no network calls at all, which is a stronger promise than a privacy policy, because there is nothing to police.

Everything lands in a SQLite index on the device, through the system library, with no third-party dependencies in the app.

Every row keeps its true rank.

Searching the library filters the list without renumbering it, so your four hundredth track still says four hundred. Each row opens a page with its rank, headline numbers, hours by year, and month by month, and the links between track, artist, and album go both ways.

The full export, 356,418 plays across nine years, imports in under four seconds. Every library screen runs its queries in under 100 milliseconds, so moving between years feels like turning pages.

A track page in Backtrack: Sweet by Cigarettes After Sex, the number one track of all time, with hours by year and month

The engine has no screens.

Parsing, the index, and every question generator live in a plain Swift package with 48 tests. The screens only render what the engine hands them, and a command line tool on the Mac imports an export and prints what each game would ask.

A web or Android version needs new screens, not new logic.

356,418plays read from one export
4seconds, at most, to import nine years
48tests on the engine
0network calls, ever

Where it stands

Working today

Import from a zip, a folder, or loose files, all three games with streaks and best scores, the library tab, and the merge of the quicker account download onto the full export.

Next

Era bosses, one level per year. Audio clips through MusicKit previews. Head to head against a friend's export. An app icon, and a real name.

Have an idea that deserves this kind of care?