pattern

Semantic Token Indirection

also called Token Tier Layering, Role Named Tokens

Naming design tokens after the role they play rather than the value they hold, so a rebrand or a new theme changes one mapping layer instead of every component and every consuming application.

design-systemdesign-tokensthemingrebrandcss-custom-properties

A rebrand changes the brand blue. The design system holds 1,100 tokens, and blue-600 appears in roughly 340 declarations across 11 applications. Changing blue-600 changes every use of that colour — including the uses that were never brand colour. The informational banner, the selected table row and the focus ring were all blue-600 because they happened to be that shade.

So the rebrand ships with a focus ring in the new brand colour, an information banner that reads as a call to action, and a week of corrections in eleven repositories. The tokens recorded what the colour was, not what it was for, and only the second fact survives a rebrand.

Why it matters

A token named after its value is a constant with extra ceremony. Indirection makes the meaning the thing consumers reference:

  • Primitive layer — blue-600: #1d4ed8. Values, never referenced by a component.
  • Semantic layer — color-action-primary: {blue-600}, color-focus-ring: {blue-600}. Roles. This is the layer a rebrand or a theme edits.
  • Component layer — button-primary-background: {color-action-primary}. Deliberate deviations.

Three layers is the number. Two cannot separate "the brand changed" from "this role changed", and four is bookkeeping nobody maintains. The payoff: a rebrand becomes an edit to the primitive layer plus a review of the semantic mappings, and the 340 declarations are untouched because none of them named a colour.

Implementation patterns

  • Name by role and state, never by appearance. color-surface-raised, color-text-on-action. A token called grey-200 has already lost the information.
  • Resolve primitives at build time and semantics at runtime through CSS custom properties. The custom property is the indirection made visible to the browser, which turns a dark theme into a class toggle rather than a second build.
  • Enforce the layering with a lint rule forbidding primitive tokens outside the semantic definition files. Without a mechanical enforcement point the layering is a convention, and in a 40-consumer system conventions decay within about 180 days.
  • Ship contrast pairs as pairs. color-text-on-action is published with color-action-primary, so accessible contrast is a property of the pair rather than of each consumer's judgement.

Industry example

The interchange format developed by the Design Tokens Community Group encodes this structure directly: a token's value may be a reference to another token rather than a literal, making aliasing a first-class concept. That the format needed it is the evidence — tools exchanging tokens between design and code found flat value tokens insufficient in practice.

The failure it prevents is the one the library documents from the other direction: two applications in one company shipping what should be the same primary button, differing by one step after a rebrand. Flat tokens make that the default outcome, because the only route to consistency is every team picking the same value every time.

Failure scenarios

  • Over-tokenisation without semantics. 1,100 tokens and no role names, so designers paste hex values. The count rises and adherence falls.
  • One semantic token carrying two meanings. color-accent used for selection and for brand, so the next brand change breaks selection and nobody predicted it.
  • Runtime indirection where build-time values are required. Media query breakpoints cannot be custom properties, so that part of the layer silently does not apply.
  • A token change released as a patch. Spacing and colour are observable contract even when no prop changed, so layouts break in production while the version number says they should not.

Trade-offs

Choose Gains Pays
Three-layer indirection one-edit rebrand, real theming, accessible pairs by construction a vocabulary everyone must learn, an extra lookup when reading code, a lint rule to maintain
Flat value tokens immediately legible, zero ceremony every theme or brand change is a find-and-replace across every consumer, with intent indistinguishable

The hidden cost is cognitive: a developer reading color-surface-raised cannot see the colour. The mitigation is tooling, not abandoning the layer.

When not to use it

One application, one brand, one theme, no rebrand in prospect: flat tokens are correct, and indirection buys optionality nobody will exercise while charging every reader a lookup. The decision flips the moment a second theme or a second brand appears, and the retrofit costs roughly one engineer-month per consuming application, because every usage has to be re-decided by meaning and that judgement cannot be automated.

Interview question

Q: "A company with eleven applications is rebranding in four months. Their design system has 1,100 tokens named by value. What do you do first, how do you sequence it so product teams keep shipping, and what do you tell the brand team they will not get this time?"

What a strong answer covers: the semantic layer introduced additively so both schemes coexist; migration by usage frequency; the lint rule as the thing that stops regression; progress measured in remaining primitive references per application; and the limit, which is that only the second rebrand is cheap.

Quick check

Quiz: Why does changing blue-600 break a rebrand? — The name records the value, so every role that used that shade changes together, including focus rings and informational states that were never brand colour.

Flashcard: What are the three token layers and which one does a rebrand edit? — Primitive (values), semantic (roles), component (deviations); a rebrand edits primitives, reviews semantics, and touches no component code.