ADR-0024: Rebrand the project from spotify-clone to Bitrate
Status: Accepted
Date: 2026-09-02
Context
The repository was built as a Spotify clone and carried that everywhere: the @spotify/*
package namespace, the spotify-clone repository name, Postgres databases and a Docker network
named after it, Spotify's green #1db954 as the product's primary colour, Spotify's logo mark,
and — most consequentially — marketing copy lifted verbatim from Spotify for Artists, including
© 2026 Spotify AB, a real recording artist presented as a Spotify for Artists user, and
Spotify's registered product names (Canvas, Marquee, Discovery Mode, Loud & Clear, Showcase).
PRODUCT.md had described that identity as "scaffolding" pending a rebrand, but the rebrand had
no target. apps/docs/docs/brand/brand.md and its sibling design.md now define one: Bitrate — all-in-one for musicians,
with a brand board fixing the palette and three themes. The resemblance was no longer a
placeholder waiting on a decision; it was an unbounded liability sitting in a public repository.
Decision
Rebrand to Bitrate across every layer, in five ordered phases, each independently verifiable:
- Package namespace —
@spotify/*to@bitrate/*across 14 workspaces. - Repository identity — repository metadata, root docs,
.claude/, the Docusaurus site, GitHub URLs, and the Expo app's bundle identifier. - Infrastructure — Postgres databases, Docker network and containers, container-image OS users, the mail sender, the admin panel's Knex data source, Prometheus metric names, and the Redis rate-limit key prefix.
- Visual identity — the palette and semantic roles in
packages/ui-react/src/styles/, a third theme, client storage keys. - Copy — every user-facing string that named Spotify.
brand.md is the source of truth for positioning, promise, and tone; design.md for design
rules — both under apps/docs/docs/brand/; apps/docs/docs/brand/bitrate-brand-board.png for the palette and theme values.
packages/ui-react/src/styles/ remains the only source for token values themselves — see
ADR-0023.
Three decisions inside those phases are worth recording, because each is a place where the obvious mechanical answer was wrong:
Historical documents keep the old names. @spotify/tokens and @spotify/tokens-generator
were removed by ADR-0023 before this rebrand. The ADRs, blog post, and changeset that narrate
their removal still say @spotify/*, because no package ever existed under @bitrate/tokens and
renaming it there would fabricate history.
Spotify's product names became descriptions, not new Bitrate product names. Replacing only
the word "Spotify" in apps/web-artists would have left Canvas, Marquee, and Loud & Clear
standing under Bitrate's banner — a worse outcome than before, since it would read as Bitrate
claiming another company's products. Inventing Bitrate equivalents would have been a product
decision this rebrand had no authority to make. Each became a plain description of what the
capability does.
Copy that would have become a false claim was rewritten, not translated. The landing page
carried Spotify's real "517.69 million+ users worldwide"; under Bitrate that is a fabricated
metric, which brand.md §12 forbids. It now asserts no number. A testimonial naming a real
artist was rewritten without her rather than re-attributed.
Dim is a partial theme. The brand board specifies eight tokens for dim. :root.dim
overrides only those; every other role, component-scoped roles included, inherits its dark
value. Requiring a dim block in all 22 part-files would mean inventing values the brand has not
decided.
Consequences
Breaking, and accepted deliberately:
- Prometheus metrics renamed
spotify_api_http_*tobitrate_api_http_*. Dashboards and alerts on the old names return no data. - Redis rate-limit prefix changed, so in-flight counters reset once at deploy.
- Postgres databases renamed. Existing environments need the volume recreated and migrations
and seed re-run;
.env,apps/api/.env.development, andapps/api/.env.testmust be updated by hand. - Client storage keys and the service-worker cache renamed. Saved playlists, recent searches, player position, restored session, and settings do not carry over.
- TOTP issuer changed from
SpotifytoBitrate. Enrolled authenticator entries keep working but appear under a second entry; users should re-scan. - Mobile and desktop bundle identifiers changed, so existing installs and deep links do not
carry over. They stay owner-namespaced (
com.lordpluha.*) rather than claiming abitrate.*domain, becausebrand.md§17 makes the name conditional on trademark and domain clearance. - Screenshot baselines are all stale; the entire palette changed.
Explicitly out of scope, and still open:
- The logo. At the time of this ADR no Bitrate mark existed, so
SpotifyLogo, its SVG asset,aria-label="Spotify Home", andpublic/icon.svgwere left in place on purpose. Superseded: the mark arrived and all four were replaced —design.md§24 is now the contract. The wordmark is still raster-only, which is what keeps the lockup slots square. - The Vercel preview host
spotify-clone-web-olive.vercel.app, kept until the deployment is renamed. - Renaming the GitHub repository and the local checkout, which is a manual step; URLs in the
repo already point at
github.com/Lordpluha/bitrate.
Alternatives considered
- Rebrand in one commit — rejected. A single change spanning namespace, infrastructure,
palette, and copy is unreviewable, and a failure anywhere makes the whole thing unbisectable.
Five phases each pass
build,check-types,lint, and the test suites on their own. - Keep the
@spotify/*namespace — rejected. Nothing publishes to npm, so the namespace is cosmetic, but it is the string that appears in every import in the repository and is the single most visible carrier of the old identity. - Leave infrastructure identifiers alone — rejected. They cost a volume recreation once, and leaving them means the name survives in the place hardest to change later, once production data exists.
- Rename Spotify's product names to Bitrate equivalents — rejected as out of authority; see the Decision section.