Open any aging codebase and count the grays; forty is normal. Nobody planned forty — it piled up one hardcoded #f3f3f3 at a time, because there was no name to reach for. Tokens fix that: every visual decision gets one name, defined once and used everywhere.
Semantic beats raw
The first mistake is naming a token after what it looks like. --color-blue-500 lies the day you rebrand to purple, and now every new hire has to learn that blue means purple. Name by purpose instead.
The four semantic tokens you’ll reach for first are background, foreground, border, and primary. A component that says bg-primary doesn’t care what primary is today; change the value once and the meaning travels everywhere it’s used. That indirection is the entire point of a token.
The three tiers
Structure tokens in three tiers. Primitives are the raw palette — --blue-600, --gray-50, --space-4 — and never appear in component code. Semantic tokens map purpose onto them, so --primary points at --blue-600.
The third tier is optional: component tokens for one stubborn case, like --button-radius. Rebrand by swapping primitives, add dark mode by swapping the semantic layer, tweak one button with a component token — each change stays at exactly one level.
Sync to Tailwind
Tokens only earn their keep when your utility classes read from them. Define the values as CSS variables, then point your Tailwind theme at those variables so bg-primary and border-border resolve through the whole chain.
:root {
/* primitives — raw palette, never used in components */
--blue-600: 221 83% 53%;
--gray-50: 210 20% 98%;
/* semantic — points at primitives */
--primary: var(--blue-600);
--background: var(--gray-50);
}
@theme inline {
--color-primary: hsl(var(--primary));
--color-background: hsl(var(--background));
}Now bg-primary pulls straight from the token chain. Switch themes by reassigning the CSS variables at runtime — no rebuild, no component edits, no find-and-replace across two hundred files. Design tools can point at the same variables, so a color change starts in one place and ends in one place.
Ship it
Start with one file and about fifteen tokens: four colors, a spacing scale, three radii. Wire them into your theme, then delete every hardcoded value they replace. Colors and spacing first; they touch every screen.
You don’t need Style Dictionary or a Figma pipeline on day one. You need one place every value lives and the discipline to reach for it. Add the automation later, once the names have proven they’re right.