Semantic tokens and primitive tokens need separate layers
Aliases: primitive token · semantic token · token alias · two-layer tokens
What it is
Tokens have to sit in two layers so you can change the pigment without rewriting the contract at the call site. A primitive token names a raw material: a step of blue, a spacing increment. A semantic token names a role — primary action, canvas surface, danger foreground — and aliases to a primitive. Call sites bind to roles, not to materials.
This is alias layering, not a private token set per component. A button’s own fill/stroke mapping is a third, component-scoped layer and is out of scope here.
Why it happens
Primitives answer “what materials are in the warehouse.” The semantic layer answers “which material does this role use right now.” If product code writes blue.600 directly, a brand shift of that blue drags every coincidental use with it — primary buttons, links, and series 3 on a chart. Semantic aliases split “primary action” from “chart series,” even when they happen to point at the same blue today.
The alias is the actual product: semantic names stay stable, primitives stay replaceable. Skip the layer and a color change becomes a global find-and-replace. Keep the layer but make every semantic a 1:1 rename of a primitive, and you pay lookup cost with no isolation. Component-level tokens sit below that: they wire one component’s parts to the semantic layer and are not for reuse by other components.
Where it stops holding
A tiny tool with a single surface color can collapse the two layers for a while; the collapse bites as soon as one material serves two roles. If a “semantic” name is just color.blue.600 — a rebadge of the primitive with no role — the layering is fake. Print and HTML email pipelines that cannot resolve aliases at runtime need the semantic layer flattened at build time; they cannot assume a live indirection.
Applying it
- Split the token source into a primitive file and a semantic file; the semantic file may contain aliases only, never raw hex or pixels.
- Components and page styles reference semantic names only; primitive names must not appear at call sites.
- Rehearse a primary-color change by retargeting aliases, not by editing components.
- How to check: point the primary-action alias at a different primitive and rebuild. The primary button should move; the chart series should not. If both move, call sites were bound to the material.
Related
- Same group: R1.01.1 Tokens turn design decisions into named, distributable values · R1.01.3 Using raw values directly bypasses the system · R1.01.4 Theme switching retargets the semantic layer, not raw values
- Nearby: R1.09 Token layers and semantic naming · R1.15 Multi-brand and multi-theme
- Search terms:
primitive-semantic layering·semantic token·token alias