Lesson 22 of 26
Theming and Design Tokens
Design tokens as the layer that separates a design decision from where it's used, and how that separation is what makes theming, dark mode and rebrands tractable.
A rebrand, a new theme, or dark mode support should not require touching every component in a design system one at a time. That they don't have to is entirely because of one architectural decision: design tokens, which separate what a design decision is from where it's used.
What a token actually is
A token is a named, indirect reference to a design value — a color, a spacing unit, a font size, a border radius — rather than the raw value itself, used directly at every place it's needed:
// Without tokens: the same raw value, copy-pasted everywhere it's needed.
// button.css
color: #3B82F6;
// link.css
color: #3B82F6;
// With tokens: one definition, referenced everywhere.
const tokens = {
color: {
primary: "#3B82F6",
},
};
// button.css and link.css both reference tokens.color.primaryThe value isn't the naming itself — it's that the actual value now lives
in exactly one place. Changing tokens.color.primary once propagates to
every component that referenced it, with zero changes required in those
components. Compare that to hard-coded values: updating a brand color means
finding every literal occurrence of that hex value across the codebase,
which is exactly the kind of task that's easy to almost get right and hard
to get completely right.
Semantic tokens: the layer that makes theming actually work
The deeper payoff comes from a second level of indirection: semantic
tokens, named for their role rather than their literal value —
color.background, color.text.primary, color.border.danger — which
themselves reference the raw value tokens.
Raw value tokens
The actual values — a specific blue hex code, a specific spacing number. Rarely referenced directly by components.
Semantic tokens
Named for role, not value — color.background, color.text.primary. Components reference these, not raw values.
Components
Reference only semantic tokens. Never hard-code a raw value or know which theme is currently active.
Components should reference only semantic tokens, and should have no
awareness of whether light or dark mode (or any other theme) is currently
active. Dark mode, then, is implemented once, at the token layer: define
what color.background and color.text.primary resolve to for a dark
theme, and every component that already referenced those semantic tokens
picks up the new values automatically — with literally zero changes to any
component's own code, precisely because none of them ever hard-coded a raw
value or branched on the active theme themselves.
Where tokens actually live and how they reach code
In practice, tokens are usually authored once, often in a format like the W3C Design Tokens spec or a tool like Style Dictionary, and then compiled into whatever a given platform actually consumes — CSS custom properties for the web, a Swift/Kotlin constants file for native platforms, a Figma variables collection for designers working in the design tool itself. This is what lets a single design decision — "the brand's primary color is changing" — update consistently across web, native apps, and design mockups from one source of truth, rather than three separately maintained copies inevitably drifting out of sync with each other over time.
The discipline this requires from component authors
None of this works if component authors quietly reach for a raw value "just this once" because the right semantic token doesn't quite exist yet — that one hard-coded value is invisible to the token system entirely, and silently won't update the next time a rebrand or theme change happens. The actual discipline design tokens require is refusing that shortcut: if the right semantic token doesn't exist, that's a signal to add one (a genuine gap in the token vocabulary), not a license to hard-code a value locally and lose the entire benefit for that one spot.
What to remember
- A token is a named, indirect reference to a design value — the actual value lives in one place, and everywhere that references the token updates automatically when it changes.
- Semantic tokens (named for role — background, text, border — not literal value) are what components should reference, never raw values directly.
- Dark mode and rebrands become single, centralized changes at the token layer, with zero changes to component code, as long as components never hard-code raw values.
- A hard-coded value anywhere in a component is invisible to the token system and will silently fail to update on the next theme change — treat that as a missing token, not an acceptable shortcut.
Check yourself
3 questions · pass 3/3 to unlock How to Approach a Frontend System Design Interview
1.A component library hard-codes
color: #3B82F6directly inside dozens of components wherever the brand's primary blue is needed. What problem does this cause when the brand color changes?2.What is a design token, and what does referencing
color.primaryinstead of a raw hex value actually buy you?3.How do design tokens make dark mode tractable, compared to writing separate dark-mode styles for every component individually?
3 left to answer