Design Tokens: The Complete Guide
Design tokens are named values that encode visual decisions. DESIGN.md organizes them into four frontmatter maps (colors, typography, spacing, rounded) plus a components section that references them with a {path.to.token} syntax. From there, the CLI exports to a Tailwind v4 @theme block or a DTCG JSON file in a single command.
What design tokens are#
A design token is a name-value pair that replaces a hardcoded value with a shared, documented decision. Instead of #3B82F6 scattered across forty files, you define it once and reference the name everywhere. The token carries intent (tertiary signals "interactive element"); the raw hex value does not.
Tokens let you:
- Update a value in one place and propagate it to every consumer.
- Communicate purpose through naming rather than raw values.
- Export to multiple target formats (CSS custom properties, Tailwind theme, W3C DTCG) from one source of truth.
For a deeper introduction with worked examples, read Design Tokens Explained.
The three-tier model#
The widely-taught community model splits tokens into three tiers. DESIGN.md covers all three.
Tier 1: Global tokens (primitive / raw)#
Global tokens enumerate the raw palette. They have no opinion about usage; they just record what values exist. Renaming them is a breaking change.
colors:
blue-500: "#3B82F6"
gray-900: "#111827"
red-600: "#DC2626"
DESIGN.md can hold global tokens under colors, spacing, and rounded, though the spec defaults to semantic names at this tier.
Tier 2: Semantic tokens (alias / role)#
Semantic tokens map an intent onto a value. They answer "where is this used?" rather than "what color is this?"
colors:
primary: "#111827" # dominant text, main brand chrome
secondary: "#6B7280" # supporting text, metadata
tertiary: "#3B82F6" # interactive elements, CTAs
surface: "#FFFFFF" # card and panel backgrounds
on-surface: "#111827" # text placed on a surface
error: "#DC2626" # destructive actions, error states
DESIGN.md works at this tier by default. The spec recommends the seven names above (primary, secondary, tertiary, neutral, surface, on-surface, error) because agents and exporters recognize them. Missing a primary key when colors are otherwise defined triggers a missing-primary warning.
Tier 3: Component tokens#
Component tokens bind semantic values to a specific UI element. They are the most specific tier and the most frequently changed.
components:
button-primary:
backgroundColor: "{colors.tertiary}"
textColor: "#ffffff"
typography: "{typography.label-md}"
rounded: "{rounded.md}"
padding: 12px
button-primary-hover:
backgroundColor: "{colors.secondary}"
The {colors.tertiary} notation is the DESIGN.md reference syntax. A reference that points to a key that does not exist triggers a broken-ref error at lint time.
How DESIGN.md expresses each token type#
Colors (colors)#
Color tokens are name-to-hex pairs under the colors key. The value must be # followed by exactly six hexadecimal digits (sRGB).
colors:
primary: "#1A1C1E"
secondary: "#6C7278"
tertiary: "#B8422E"
neutral: "#F7F5F2"
The linter runs a WCAG AA contrast check (4.5:1 minimum) on every component pair that has both a backgroundColor and a textColor. Full details: Colors reference.
Typography (typography)#
Typography tokens are named objects. Each object can carry up to seven sub-fields:
All sub-fields are optional. Spec-recommended token names: headline-display, headline-lg, headline-md, body-lg, body-md, body-sm, label-lg, label-md, label-sm. Full details: Typography reference.
Spacing (spacing) and Rounding (rounded)#
Both are name-to-dimension maps. A dimension is a number followed by px, em, or rem.
rounded:
none: 0px
sm: 4px
md: 8px
lg: 16px
xl: 24px
full: 9999px
spacing:
sm: 8px
md: 16px
lg: 32px
Spec-recommended rounded names: none, sm, md, lg, xl, full.
Components (components)#
Component tokens bind a UI component to values from the tiers above. Each component entry is a named object whose properties can be literal values or token references.
Component sub-token properties recognized by the spec:
Variant states (hover, active, pressed, disabled, focus, selected, checked) are expressed as separate keys suffixed to the base component name, e.g. button-primary-hover.
The reference syntax#
The {path.to.token} syntax is how DESIGN.md wires tier 3 back to tier 2 (and tier 2 back to tier 1). The path is dot-separated and starts with the frontmatter key:
| Reference | Resolves to |
|---|---|
{colors.tertiary} | The hex value of the tertiary color token |
{typography.label-md} | The full typography object for label-md |
{rounded.md} | The dimension value of the md rounded step |
The linter resolves every reference at lint time. A path that does not match a defined key is a broken-ref error (severity: error, file rejected). The parser supports up to 10 levels of reference depth and 20 levels of nesting. Cycles beyond those limits are also flagged as broken.
How tokens flow out#
To Tailwind v4#
The css-tailwind export target maps every DESIGN.md token to a Tailwind v4 @theme CSS block. One command:
npx @google/design.md export DESIGN.md --format css-tailwind > tokens.css
Token sections map to CSS variable families:
| DESIGN.md section | CSS variable prefix |
|---|---|
colors | --color- |
typography.fontFamily | --font- |
typography.fontSize | --text- |
typography.lineHeight | --leading- |
typography.letterSpacing | --tracking- |
typography.fontWeight | --font-weight- |
rounded | --radius- |
spacing | --spacing- |
Paste the @theme block into your globals.css alongside @import "tailwindcss" and the token names become utility class suffixes immediately. Step-by-step walkthrough: DESIGN.md to Tailwind v4 Theme.
To DTCG#
The dtcg export target emits a W3C Design Tokens Community Group JSON file:
npx @google/design.md export DESIGN.md --format dtcg > tokens.json
The output uses $schema: https://www.designtokens.org/schemas/2025.10/format.json, groups tokens by type, and expresses color values as sRGB component arrays with a hex convenience field. DESIGN.md can be your source of truth for human and agent use while still feeding DTCG-based tool pipelines. When to use each format: DESIGN.md vs DTCG.
All four export formats#
| Format flag | Output |
|---|---|
css-tailwind | Tailwind v4 @theme block |
json-tailwind | Tailwind v3 theme.extend JSON |
tailwind | Alias for json-tailwind |
dtcg | W3C DTCG JSON |
Reference integrity: what the linter checks#
| Rule | Severity | What it catches |
|---|---|---|
broken-ref | error | A {reference} path that resolves to no defined token |
missing-primary | warning | Colors defined but no primary key present |
missing-typography | warning | Colors defined but typography is empty |
contrast-ratio | warning | Component backgroundColor/textColor pair below WCAG AA 4.5:1 |
orphaned-tokens | warning | A color token defined but never referenced by any component |
section-order | warning | Markdown sections appear out of canonical order |
Where to go next#
Spec section references (dive into a specific token type)
- Colors: hex format, reference syntax, WCAG AA contrast lint, orphaned-token rule
- Typography: all seven sub-fields, variable font support, linter rules
Learn articles (deeper explanation of the concepts above)
- Design Tokens Explained: a full walkthrough of the three-tier model with DESIGN.md examples
- DESIGN.md to Tailwind v4 Theme: step-by-step export and integration guide
- DESIGN.md vs DTCG: when to use each format and how the CLI bridges them
Was this page helpful?