How to Build a Design Token System from Scratch
Step-by-step guide to building a design token system: naming conventions, token tiers, CSS variable output, and Figma integration for product teams.
When components repeat raw colors, spacing values, and type sizes, a design change can require edits across many files. Design tokens give those decisions names and a shared source that components can reference.
What Is a Design Token System
Design tokens are named variables that store a single design decision: a color, a spacing value, a typeface, a shadow. The token color.brand.primary carries the value #1A73E8. When that value changes, you update one place and every component that references the token inherits the change.
A design token system is the architecture governing how tokens are named, tiered, output to different platforms, and connected between design tools and code.
The Three-Tier Token Model
A three-tier model separates primitive, semantic, and component tokens.
Tier 1: Primitive tokens
Primitive tokens are raw values with no context attached.
color.palette.blue.500 = #1A73E8
color.palette.blue.600 = #1557B0
spacing.4 = 16px
font.size.base = 16px
In this model, primitives define the palette and components normally consume semantic tokens.
Tier 2: Semantic tokens
Semantic tokens alias into primitives and carry intent. They describe roles, not values.
color.action.primary = color.palette.blue.500
color.action.primary-hover = color.palette.blue.600
color.text.default = color.palette.neutral.900
spacing.component.padding-sm = spacing.4
This tier is what your component library consumes. It is also what you swap when switching themes or color modes.
Tier 3: Component tokens
Component tokens alias into semantic tokens and describe decisions scoped to one component.
button.background.default = color.action.primary
button.background.hover = color.action.primary-hover
button.padding-x = spacing.component.padding-sm
Not every team needs tier three. Add it when multiple components share semantic tokens but diverge in ways that semantic tokens cannot express cleanly.
How to Build a Design Token System Step by Step
1. Audit what exists
Before naming a single token, list every raw value currently hardcoded in your codebase or design files. Group by category: colors, spacing, type, shadows, border radii, durations. You will find duplicates, near-duplicates, and values that belong to no obvious system.
2. Define your primitives
Create a complete palette for each category. For color, generate a full scale (50 through 900 for each hue). For spacing, use a base unit (typically 4px or 8px) and define multiples: spacing.1 = 4px, spacing.2 = 8px, and so on up to your maximum. For type, define a scale based on a consistent ratio.
3. Use Consistent, Descriptive Names
Token names must be readable by both designers and engineers. Use dot notation or kebab-case consistently. Be descriptive at the semantic layer:
- Good:
color.feedback.error,color.text.disabled - Avoid:
color.red,color.gray3
Role-based names tell a developer where to use a semantic token.
4. Output tokens to each platform
Tokens live in a format-agnostic source — typically JSON or YAML — and are transformed into platform-specific outputs using a tool like Style Dictionary.
For web: CSS custom properties or JavaScript objects. For iOS: Swift color definitions. For Android: XML color resources.
CSS output from color.action.primary:
:root {
--color-action-primary: #1a73e8;
}5. Connect Figma to your token source
Use a plugin like Tokens Studio (formerly Figma Tokens) to sync your token source with Figma variables. This closes the gap between design and code: when a token changes in the source, designers and engineers see the same value.
6. Implement dark mode through semantic tokens only
This example implements dark mode by mapping semantic tokens to different primitives.
/* Light */
color.surface.default = color.palette.neutral.50
/* Dark */
color.surface.default = color.palette.neutral.900
For theme changes covered by these tokens, update the semantic mapping and verify the affected components.
Common Mistakes to Avoid
- Skipping the primitive tier and aliasing semantic tokens directly to hex values. Now theme changes require editing every semantic token.
- Naming by value rather than role.
color.bluebreaks the moment your brand changes or a dark theme inverts the meaning. - Defining tokens in design tools but not in code. The source of truth must be a version-controlled file, not a Figma library.
- Ignoring accessibility metadata. Document which color tokens meet WCAG contrast thresholds and for what background. That information belongs in the token spec.
Maintaining the Token System Over Time
Before adding a token, check whether an existing semantic token covers the need. Overlapping names make it harder to choose the right token and understand the effects of a change.
Assign a single owner to the token layer. Run token changes through a review process that includes at least one designer and one engineer. Treat the token source file as a core dependency with a changelog.