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"
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:

Sub-fieldTypeNotes
fontFamilystringCSS font-family name
fontSizeDimensione.g. 16px, 1.5rem
fontWeightnumbere.g. 400, 700
lineHeightDimension or numberunitless multiplier or dimension
letterSpacingDimensione.g. "-0.02em"
fontFeaturestringCSS font-feature-settings value
fontVariationstringCSS font-variation-settings value

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:

PropertyType
backgroundColorColor
textColorColor
typographyTypography reference
roundedDimension
paddingDimension
sizeDimension
heightDimension
widthDimension

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:

ReferenceResolves 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 sectionCSS 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 flagOutput
css-tailwindTailwind v4 @theme block
json-tailwindTailwind v3 theme.extend JSON
tailwindAlias for json-tailwind
dtcgW3C DTCG JSON

Reference integrity: what the linter checks#

RuleSeverityWhat it catches
broken-referrorA {reference} path that resolves to no defined token
missing-primarywarningColors defined but no primary key present
missing-typographywarningColors defined but typography is empty
contrast-ratiowarningComponent backgroundColor/textColor pair below WCAG AA 4.5:1
orphaned-tokenswarningA color token defined but never referenced by any component
section-orderwarningMarkdown 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)

Try it in the tool

Was this page helpful?