The Problem
Without a token system, CSS becomes tribal knowledge. One developer uses `#3b82f6`, another uses `blue-500`, a third hardcodes `rgba(59,130,246,1)`. A brand refresh means a global find-and-replace — and you'll still miss something.
The Solution
A three-layer token architecture gives you one source of truth. Change a primitive, and the semantic and component layers update automatically. Brand refreshes become a one-file edit.
Three Layers of Tokens
Effective token systems use three layers: primitive (raw values), semantic (roles), and component (local overrides). Each layer references the one below it — never skip layers.
/* Primitive */
--blue-500: #3b82f6;
/* Semantic */
--color-action: var(--blue-500);
/* Component */
--btn-bg: var(--color-action);Building Your Token System
Define primitive tokens
Primitive tokens are raw values — every color, spacing step, and type size your brand uses. Name them by value, not role: `--blue-500`, `--space-4`, `--text-sm`.
Map semantic tokens
Semantic tokens assign role to primitive values: `--color-action: var(--blue-500)`. These are what your UI actually consumes — and what you swap during a brand refresh.
Add component tokens
Component tokens are local overrides: `--btn-bg: var(--color-action)`. They isolate components so changing a semantic token doesn't break unexpected UI.
Automate with Style Dictionary
Use Style Dictionary to transform your JSON token source into CSS variables, Tailwind theme values, iOS Swift, and Android XML simultaneously.
Key Takeaways
- Never skip token layers — primitive → semantic → component is the critical chain
- Semantic tokens are what you swap during brand refreshes, not primitives
- Component tokens prevent cascade bleed between unrelated UI elements
- Style Dictionary automates multi-platform token output from a single JSON source
Frequently Asked Questions
Both — CSS variables for runtime theming, JS constants (via Style Dictionary output) for type-safe access in components. Generate both from the same JSON source.
