How to Build a Design Token System That Survives a Rebrand

A row of color swatches and paint chips arranged by hue

The first sign a design token system is broken shows up during a rebrand, not before. Someone updates the primary brand color in one place, ships it, and half the product still shows the old blue because a dozen components had it hardcoded, or worse, referenced a token that was never meant to carry brand meaning in the first place.

A token system that actually survives change is built on roles and tiers, not just a list of hex codes with friendly names. This article walks through that structure, why flat token lists fall apart, and how to migrate an existing color palette into one without breaking every page at once.

Why a flat list of color variables isn't a token system

Plenty of teams call --brand-blue: #1a73e8; a design token and stop there. That's a CSS variable, not a token system, because nothing in it says what the color is for. When the brand color changes, you're left grepping the codebase for every place --brand-blue was used to figure out which uses were actually brand-related and which were incidental.

typography poster with large letterforms
Photo by Hurrah suhail on Pexels

A design system worth the name separates raw values from the roles they play. The raw value layer holds the actual colors, spacing units, and font sizes. A semantic layer on top maps each role, like "primary action background" or "danger text", to one of those raw values. Components reference only the semantic layer, never the raw one.

That separation is the entire point. It means a component author never has to know or care what the actual hex value behind "danger text" is, only that red text for an error state should use that role. When the brand's red changes six months from now, every component using that role updates automatically, because none of them ever hardcoded the value in the first place.

The three-tier structure that makes rebrands cheap

Most durable token systems use three tiers. Getting this right up front is the single biggest factor in whether a future rebrand takes an afternoon or a quarter.

Tier 1: primitives. The raw palette, unopinionated about meaning: blue-500: #1a73e8, space-4: 16px, font-size-md: 16px. These rarely change once set, because they're just a numbered scale, not a brand decision.

Tier 2: semantic tokens. These carry meaning and point at a primitive: color-action-primary: {blue-500}, color-text-danger: {red-600}. A rebrand touches this layer, remapping which primitive each semantic role points to, without renaming the roles themselves.

Tier 3: component tokens. Scoped to a specific component when it needs to diverge from the general semantic value: button-primary-background: {color-action-primary}. Most components should skip this tier entirely and reference semantic tokens directly; add a component tier only when a specific component genuinely needs an override.

A working token file in practice

Here's a trimmed example showing all three tiers for a single color family, written as design tokens that a build step can transform into CSS custom properties, iOS or Android resources, or whatever your platforms need.

{
  "color": {
    "blue": { "500": { "value": "#1a73e8" } },
    "red": { "600": { "value": "#c5221f" } }
  },
  "semantic": {
    "action-primary": { "value": "{color.blue.500}" },
    "text-danger": { "value": "{color.red.600}" }
  },
  "component": {
    "button-primary-bg": { "value": "{semantic.action-primary}" }
  }
}

Tools that consume a token structure like this can generate per-platform output automatically, so designers working in Figma and engineers writing Sass or CSS custom properties stay on the same source of truth instead of quietly drifting apart.

Naming tokens by role, not by appearance

The most common naming mistake is describing what a token looks like instead of what it does: color-blue instead of color-action-primary. The moment your brand color stops being blue, every reference to color-blue becomes a lie that still technically works, which is worse than a broken reference because nobody notices it.

architecture blueprint with pencil and ruler on a drafting table
Photo by Czapp Árpád on Pexels

Name by role: surface-elevated, border-subtle, text-inverse. A developer reading text-inverse in a component knows exactly when to reach for it, regardless of whether the underlying value is white, off-white, or something else after the next brand refresh.

Handling dark mode without doubling your token count

Dark mode is a rebrand that happens at runtime instead of in a design review. If your semantic tokens already separate meaning from raw value, supporting a theme is just swapping which primitive each semantic token resolves to under a prefers-color-scheme or a manual theme toggle, not writing a second complete set of component styles.

:root {
  --color-surface: var(--gray-50);
  --color-text: var(--gray-900);
}
[data-theme="dark"] {
  --color-surface: var(--gray-900);
  --color-text: var(--gray-50);
}

Components still reference --color-surface and --color-text unchanged. The prefers-color-scheme media feature on MDN documents how to detect the user's system preference automatically, but the theme swap itself happens entirely at the semantic-to-primitive mapping layer, which is exactly the boundary the three-tier structure was built to protect.

Migrating a legacy palette without breaking every page

You almost never get to design a token system from scratch. Usually there's an existing app with two hundred hardcoded hex values scattered across components, and the migration has to happen incrementally without a big-bang rewrite that risks shipping visual regressions everywhere at once.

Start by auditing which hex values actually appear in the codebase and how often. The W3C's ongoing design token format work is converging the industry on a shared JSON schema for exactly this kind of tooling, which makes audits easier as more linters adopt it. Group the found values into your primitive scale, map each usage site to the semantic token it should have used, and replace references file by file behind visual regression tests, rather than attempting a single sweeping find-and-replace.

Tokens aren't just for color

Everything in this article applies equally to spacing, typography, radius, and shadow, and skipping those layers is one of the most common half-measures. A team that tokenizes color but hardcodes margin: 24px and border-radius: 6px throughout the codebase still has to hunt down every spacing value by hand when a design refresh changes the grid from a 4px base unit to an 8px one.

{
  "space": { "1": { "value": "4px" }, "2": { "value": "8px" }, "4": { "value": "16px" } },
  "radius": { "sm": { "value": "4px" }, "md": { "value": "8px" } },
  "font-size": { "sm": { "value": "14px" }, "md": { "value": "16px" }, "lg": { "value": "20px" } }
}

Spacing and typography scales benefit from the same primitive-to-semantic split as color: a primitive numbered scale underneath, and semantic names like space-card-padding or font-size-heading-sm on top, so a redesign that tightens overall spacing is a scale adjustment in one file rather than a manual pass through every component's inline styles.

Versioning tokens like you'd version an API

Once a design token file is consumed by multiple codebases, mobile apps, a marketing site, an internal admin panel, treat changes to it with the same care as a breaking API change. Renaming or removing a token that other teams already reference will break their builds the moment they pull the update, often without a compile-time error to warn them.

Semantic versioning works well here. A patch release adjusts a primitive's value without touching any names. A minor release adds new tokens without removing old ones. A major release, reserved for actual rebrands, is the only one allowed to rename or remove tokens, and it should ship with a migration guide listing every renamed key, not just a changelog entry saying "updated tokens."

Governance: who's allowed to add a new token

A token system fails slowly when anyone can add a new token for a one-off need. Six months in, you have color-blue-but-slightly-different sitting next to color-action-primary, and nobody remembers which one is canonical.

Treat new tokens like a schema change, not a styling tweak. Require a short review before a new primitive or semantic token merges, checking whether an existing token already covers the need. This is the same discipline our UX/UI design work applies when a client's design file has accumulated a dozen near-identical shades of the same blue over a few years. - Dennis Traina, founder of 137Foundry

Testing that a rebrand actually holds

The real test of a token system isn't code review, it's remapping every semantic token to a placeholder color, like swapping every value for a shade of magenta, and looking for anything that still renders in the old palette. Anything still showing the original color has a hardcoded value or a token bypass that the migration missed.

whiteboard covered in sketches of a user flow
Photo by Jason Coudriet on Unsplash

Run this check before every rebrand, not just the first migration. It's cheap, it catches regressions from components added after the initial rollout, and it turns "did we get everything" from a guess into a verified answer.

design studio wall covered in sketches and swatches
Photo by Antoni Shkraba on Pexels

Where this pays off beyond the next rebrand

A token system built on roles instead of raw values pays for itself well before the next rebrand happens. It's what makes a client's request for a seasonal theme, a white-label variant, or an accessibility-driven contrast fix a configuration change instead of a re-engineering project.

If you're auditing an existing design system or building one from scratch, our web development service covers exactly this kind of structural work, and the services hub has the full list of what we build alongside it. You can read more about how we approach these projects on our about page.

The upfront cost of setting up three tiers instead of one flat list feels like overhead on a small project, and for a truly small one it might be. But the moment a product has more than a handful of screens, more than one platform, or a brand that's likely to evolve, that structure stops being overhead and starts being the reason a rebrand is a routine project update instead of a company-wide fire drill that pulls every team off their actual work for a month.

Need help with Web Development?

137Foundry builds custom software, AI integrations, and automation systems for businesses that need real solutions.

Book a Free Consultation View Services