Design Tokens

Design Tokens

Definition: Named, reusable values, a specific blue, a specific spacing unit, that represent a single design decision once, then get consumed consistently across design tools and code instead of being hardcoded repeatedly.

How It Works

  • A value like #0055FF gets a name like color-primary-500 instead of being pasted directly wherever that blue is needed
  • The same token name is used in both the design tool (Figma variables or styles) and the actual codebase (CSS custom properties, a theme object, platform resource files), keeping them in sync
  • Changing a token’s value in one place updates every place that references it, instead of requiring a manual find-and-replace across the whole codebase
  • Tokens are usually organized in tiers: primitive tokens hold raw values (blue-500 = #0055FF), semantic tokens name a purpose and point at a primitive (color-primary = blue-500), component tokens scope a semantic token to one component (button-bg = color-primary)
  • A build pipeline (commonly Style Dictionary) transforms one token source file into multiple platform-specific outputs automatically
  • Dark mode and theming work by swapping which primitive a semantic token points to, without touching a single component’s code
  • A token can reference another token instead of a raw value, forming a small dependency chain that a build tool resolves down to a final concrete value
  • Tokens can encode more than color: spacing scales, type scales, border radii, shadow definitions, animation durations, and breakpoints are all commonly tokenized
  • Version-controlled token files let a design change go through the same pull-request review as any other code change
  • Naming follows a predictable pattern, usually category-property-variant-state, so color-background-danger-hover is unambiguous without needing to open the file to guess its purpose
  • Tools like Figma Variables, Tokens Studio, and Style Dictionary each handle a different part of the pipeline: capturing the value, storing the source file, and transforming it into platform output
  • Token changes typically flow through the same CI pipeline as code: a pull request against tokens.json triggers a build, a visual regression check, and a review before merging

Token Tiers

TierExamplePurpose
Primitiveblue-500 = #0055FFRaw value, no meaning attached
Semanticcolor-primary = blue-500Names the value’s purpose
Componentbutton-bg = color-primaryScopes a semantic token to one component
Aliascta-bg = button-bgPoints at another token for a specific use case

Under the Hood

The token source file is the single source of truth. It’s usually plain JSON or YAML, checked into version control like any other code artifact, not a screenshot or a wiki page. A build step reads that file once and emits a different, idiomatic format for each consuming platform: CSS custom properties for web, .xcassets or Swift constants for iOS, XML resources for Android.

This is what makes tokens more than a naming convention. Because the transformation is automated, updating one value in tokens.json and re-running the build regenerates every platform’s output correctly, with no risk of a human manually retyping the hex value wrong on one of the three platforms.

Semantic tokens add a layer of indirection that primitive tokens alone don’t provide. A component styled with button-bg: color-primary never needs to change when the brand color changes, only the mapping from color-primary to a primitive token does. This indirection is also exactly how a single component supports both a light and a dark theme: color-primary resolves to a different primitive depending on which theme context is active.

Worked Example 1

  • Given: A spacing-md token is set to 16px and referenced by the padding of 30 different components across a product.
  • Step: A design review decides the product feels cramped and increases spacing-md to 20px in the token source.
  • Answer: All 30 components’ padding updates on the next build; no component’s code changes.

Worked Example 2

  • Given: A product needs a dark mode. color-surface is a semantic token currently mapped to the primitive white.
  • Step: A dark theme file remaps color-surface to the primitive gray-900 instead, without touching any component.
  • Answer: Every component using color-surface renders correctly in dark mode automatically, because none of them ever referenced white directly.

Worked Example 3

  • Given: A design audit finds 14 different hardcoded shades of blue used across a legacy codebase, none of them named or reused deliberately.
  • Step: The team consolidates them down to 5 intentional primitive tokens (blue-100 through blue-900) and replaces each hardcoded hex value with the nearest token.
  • Answer: Future color changes touch 5 named values instead of hunting through the codebase for scattered, undocumented hex codes.

Worked Example 4

  • Given: A B2B SaaS product needs to white-label its dashboard for a client whose brand color is green instead of the product’s default blue.
  • Step: The client’s build simply overrides color-primary at the semantic tier with a green primitive, leaving every component token and every component untouched.
  • Answer: A full-brand reskin ships without a single component being edited or redeployed differently.

Why It Matters

  • Makes systemic design changes, a full rebrand or a dark mode, a matter of updating token values instead of hunting down every hardcoded value in the codebase
  • Reduces the cost of supporting a new platform, since only a new output transform is needed, not a redesign of the values themselves
  • Keeps design and engineering looking at the same source of truth instead of a design file slowly drifting from what’s actually shipped
  • Enables theming (dark mode, white-labeling for different clients, high-contrast accessibility modes) without duplicating component code
  • Makes design decisions reviewable and diffable in version control, the same way code changes are
  • Cuts down on inconsistency that creeps in when many designers eyeball “close enough” colors and spacing independently
  • Supports white-labeling and multi-brand products by swapping a token set instead of maintaining separate component code per brand
  • Makes accessibility fixes, raising a contrast ratio, systemic: fix the token once instead of patching every screen that used the old value
  • Lets designers and engineers speak the same vocabulary in code review and design review, “bump space-4 to space-5” means the same specific thing to both

Common Pitfalls

  • Defining tokens but still letting hardcoded values sneak into the codebase alongside them, undermining the whole point
  • Creating too many overly specific tokens instead of a clean, small set of reusable values, recreating the same maintenance problem tokens were meant to solve
  • Naming tokens after their appearance instead of their purpose, like blue-button instead of color-primary, which breaks the moment the button needs to not be blue
  • Skipping the semantic tier and referencing primitive tokens directly from components, which makes theming impossible without editing every component
  • Letting the token source file and the design tool drift apart, so a designer’s Figma variable no longer matches the shipped CSS variable of the same name
  • Renaming a token without updating every reference, silently breaking a build instead of failing loudly
  • Treating tokens as purely a color problem and forgetting to tokenize spacing, type scale, and motion, leaving those just as hardcoded as before
  • Choosing token names that describe a specific screen instead of a reusable purpose, like homepage-hero-blue instead of color-primary
  • Assuming every value needs its own token, some genuinely one-off values are fine hardcoded, and tokenizing them just adds indirection with no reuse benefit

Comparison

Design TokensHardcoded ValuesCSS Variables AloneSass Variables
Single source of truthYesNoPartiallyPartially
Cross-platform outputYes, via build pipelineNoNo, web onlyNo, compile-time only
Runtime theme switchingYesNoYesNo, resolved at compile time
Design-tool integrationYesNoNoNo
Diffable in version controlYesScattered across filesYesYes
Consumed directly by design toolsYesNoNoNo
Survives a rebrand without touching componentsYesNoPartiallyNo
Works across web, iOS, and AndroidYesNoNoNo

Example

Google’s Material Design 3 ships a full token system (md.sys.color.primary, md.sys.color.on-primary, and similar) that Android, Flutter, and web implementations all consume, so a single color scheme change propagates identically across every platform Google supports.

Salesforce’s Lightning Design System similarly publishes its full design token set as a versioned npm package, letting any team building on the platform pull in the same values a build pipeline would generate internally.

The W3C Design Tokens Community Group is actively standardizing a common token file format so that design tools and build pipelines from different vendors can read and write the same tokens.json structure without a custom converter for every tool pairing.

Dig deeper