Design tokens: colours, spacing and themes in one source
What design tokens are, three levels from palette to components, how to name them, one card in three themes, kinds of tokens and code — with live examples.
In short
Design tokens are named design decisions: colours, spacing, radii, font sizes, shadows and durations stored in one place and used by both the layout and the code. Instead of “#E4FF4E” a button uses “color.accent”, and instead of “24 px” a card uses “space.5”. Tokens are usually built in three levels: primitives — the raw values of the palette and scales; semantic tokens — roles such as background, text and accent; component tokens — the roles applied to a specific button or card. This is what makes a dark theme, a second brand or a redesign a change of values in one file rather than a search through hundreds of styles.
Three levels of tokens
Primitives say what the colour is, roles say what it is for, component tokens say where it is used.
1Primitives
2Semantic
3Component
The key level is the middle one. Components refer to roles, not to raw colours: a button takes “color.accent”, not “lime-400”. Then a new theme only reassigns roles to other primitives — the components do not notice anything.
How to name tokens
A good name says the role, not the look. The look will change; the role stays.
| What | Bad name | Good name | Why |
|---|---|---|---|
| Main accent | green | color.accent | the accent may stop being green |
| Page background | gray-light | color.bg | in a dark theme it is dark |
| Error text | red-500 | color.danger | the role is clear in every component |
| Card padding | padding-24 | space.5 | the number may change, the step stays |
| Heading size | font-39 | font.step-4 | fluid sizes have no single number |
| Button colour | button-lime | button.bg → color.accent | the component refers to a role |
One card, three themes
Switch the theme: the card’s code stays the same, only the values of four roles change.
Solid oak table
The card’s code does not change — only the values of the roles do: background, surface, text, accent.
- color.bg
- color.surface
- color.text
- color.accent
The same mechanism gives a dark theme, a second brand on the same code, a seasonal campaign or an accessible high-contrast version. Without the level of roles each of these is a separate copy of the styles.
Kinds of tokens: not only colours
Everything that repeats in design and has a value becomes a token.
Color
color.accentSpacing
space.5 = 24pxRadius
radius.sm = 8pxType
font.step-3Shadow
shadow.mdMotion
duration.base = 280msTokens in code: a source and the result
Tokens are kept in JSON — the format with $value and $type that Style Dictionary and Tokens Studio read — and turned into CSS variables.
The source
Roles refer to primitives in curly braces — change the primitive, and every role follows.
{
"color": {
"lime-400": { "$type": "color", "$value": "#E4FF4E" },
"sage-200": { "$type": "color", "$value": "#E1E3DF" },
"graphite-950": { "$type": "color", "$value": "#171817" },
"bg": { "$type": "color", "$value": "{color.sage-200}" },
"text": { "$type": "color", "$value": "{color.graphite-950}" },
"accent": { "$type": "color", "$value": "{color.lime-400}" },
"on-accent": { "$type": "color", "$value": "{color.graphite-950}" }
},
"space": {
"4": { "$type": "dimension", "$value": "16px" },
"5": { "$type": "dimension", "$value": "24px" }
},
"duration": {
"base": { "$type": "duration", "$value": "280ms" }
}
}
CSS variables and a theme
A dark theme reassigns two roles; the button does not change.
/* Built from tokens.json: primitives once, roles for every theme */
:root {
--lime-400: #E4FF4E;
--sage-200: #E1E3DF;
--graphite-950: #171817;
--color-bg: var(--sage-200);
--color-text: var(--graphite-950);
--color-accent: var(--lime-400);
--color-on-accent: var(--graphite-950);
}
[data-theme="dark"] {
--color-bg: var(--graphite-950);
--color-text: #F8F8F8;
}
/* Components use only roles, never primitives */
.button {
background: var(--color-accent);
color: var(--color-on-accent);
}
6 rules of a token system
-
01
One source
Tokens live in one file, and both the layout tool and the code take them from it.
-
02
Components only through roles
A raw colour inside a component is a future bug of the dark theme.
-
03
Names by role
“accent”, “danger”, “surface” — not “green”, “red”, “white”.
-
04
A pair for every background
For every background role there is a text role that is readable on it.
-
05
Few levels
Three levels are enough; a fourth usually only adds confusion.
-
06
Changes through the source
Nobody edits the generated CSS by hand; it is rebuilt from tokens.
Common mistakes with design tokens
-
Tokens only in the layout
The code keeps its own colours, and after a month they no longer match.
-
Hundreds of tokens
A token for every case turns the system into a dictionary nobody reads.
-
Names by colour
“blue-button” stays blue in the name after the redesign makes it lime.
-
Skipping the roles
Components refer straight to the palette, and a dark theme requires rewriting them.
-
No text roles
Text on the accent becomes unreadable in one of the themes.
-
Manual edits to the result
The next build overwrites them, and the bug returns.
Questions about design tokens
What are design tokens in simple words?
Named design values — colours, spacing, sizes — that the layout and the code share.
How are tokens different from CSS variables?
Tokens are the source; CSS variables are one of the formats they are turned into, alongside iOS, Android and the layout tool.
Where are tokens stored?
In a JSON file in the repository; Figma variables and Tokens Studio connect it to the layout.
How many tokens does a site need?
Usually a few dozen: a palette, 10–15 roles, scales of spacing and type, radii and durations.
Do I need tokens for a small site?
A short set of CSS variables — yes, it costs nothing; a full pipeline — when there are several products or themes.
What is Style Dictionary?
A tool that turns one set of tokens into CSS, JavaScript, iOS and Android files.
Online form
Tokens
for your brand
I build token systems that connect the layout and the code: palette, roles, themes and component values in one source. Tell me about the project — I answer within one working day.