Section 1: What design tokens are
Primitive, semantic and component tokens
Most mature token systems use layers, often called tiers. Each tier references the one below it. This structure is what makes theming and large scale changes safe.
Tier 1: primitive tokens
Primitive tokens, sometimes called global or base tokens, hold raw values with names that describe the value itself:
{
"color": {
"blue": { "600": { "$value": "#0f62fe", "$type": "color" } },
"gray": { "900": { "$value": "#161616", "$type": "color" } }
}
}
Primitives are your palette and scales. They answer "what values exist?" Components should rarely use them directly.
Tier 2: semantic tokens
Semantic tokens, also called alias or system tokens, describe purpose, not appearance. They point to primitives:
{
"color": {
"text": { "primary": { "$value": "{color.gray.900}" } },
"action": { "primary": { "$value": "{color.blue.600}" } }
}
}
color.action.primary says what the colour is for. In dark mode, it might point to color.blue.400 instead. Components use semantic tokens, so switching themes means changing references, not components.
Tier 3: component tokens
Component tokens apply to a specific component, such as button.primary.background, and usually reference semantic tokens. They are useful when a component needs to differ from the general rule, or when you want teams to customise components without touching the system's semantics.
Be careful with this tier. Hundreds of component tokens that all point to the same semantic token add maintenance cost without adding flexibility. Many teams start with primitives and semantics only, and add component tokens where a real need appears.
Why layering matters
Imagine the brand moves from blue to green. With layered tokens:
- You add green primitives.
- You repoint
color.action.primaryand a few related semantics to green. - Every component updates, on every platform.
Without layers, you would search for blue hex values across the codebase and design files, and almost certainly miss some.
A quick test of your structure
Ask of each semantic token: could its value reasonably change in a different theme? If the answer is never, it may be a primitive in disguise. Ask of each component token: does any component actually need to diverge here? If not, it can probably be removed.