The Journal

Design Systems3 min read

Design Tokens: The Single Source of Truth Your Team Needs

Design tokens create a shared language between designers and developers for colors, spacing, and fonts. Learn how to set up a token system for your design system.

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.

globals.css
: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.

Frequently asked questions

What are design tokens and why do you need them?
Design tokens give every visual decision one name, defined once and used everywhere, creating a shared language for colors, spacing, and fonts between designers and developers. They prevent codebases from accumulating forty ad-hoc grays, because there's always a named value to reach for instead of a hardcoded hex.
How should you name design tokens?
Name tokens by purpose, not appearance. A token called --color-blue-500 lies the day you rebrand to purple, but --primary keeps meaning whatever primary is today. The four semantic tokens to reach for first are background, foreground, border, and primary, so a component using bg-primary never needs to know the underlying value.
How do you connect design tokens to Tailwind CSS?
Define token values as CSS variables in :root, then point your Tailwind theme at them using @theme inline so utilities like bg-primary and border-border resolve through the whole chain. You can then switch themes by reassigning the CSS variables at runtime, with no rebuild or component edits.