# 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.

- **Published:** 2025-04-03
- **Author:** Clixo
- **Reading time:** 5 min read
- **Tags:** design tokens, design systems, css variables, theming
- **Canonical URL:** https://clixo.sh/blog/how-to-build-design-token-system-from-scratch

Your engineers are hardcoding `#1A73E8` directly into components. Your designers are copying hex values from a shared doc that nobody updates. Every theme change requires a global find-and-replace that still misses something. The root cause is the same: you do not have a token system.

## 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

The most durable token architectures use three tiers: primitive, semantic, and component.

### 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
```

These are your full palette. They never appear directly in component code.

### 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.

```mermaid
flowchart TD
  A["Primitive Tokens\n(Raw values: hex, px, rem)"] --> B["Semantic Tokens\n(Role-based aliases)"]
  B --> C["Component Tokens\n(Scoped per component)"]
  C --> D["Component Code"]
  B --> D
  A --> E["Style Dictionary"]
  E --> F["CSS Variables"]
  E --> G["iOS / Android Output"]
```

## 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. Name tokens for humans, not machines

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`

The first set communicates usage. The second communicates nothing beyond the raw value.

### 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`:

```css
: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

Dark mode is not a different palette. It is a different mapping of semantic tokens to primitives.

```
/* Light */
color.surface.default = color.palette.neutral.50

/* Dark */
color.surface.default = color.palette.neutral.900
```

Swap at the semantic layer. Your component code never changes.

## 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.blue` breaks 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

Every token is a commitment. Before adding one, ask whether the need is specific enough to require its own variable or whether an existing semantic token covers it. Token sprawl is a real failure mode — systems with hundreds of overlapping semantic tokens become impossible to navigate.

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.

A well-built design token system is the first investment that pays dividends across every subsequent component you build. Get the foundation right and theming, dark mode, rebranding, and multi-product consistency become configuration changes rather than engineering projects.

[Clixo builds design token systems that span multiple products and platforms.](https://clixo.sh/#contact)

---

Clixo · 1141 W Bryn Mawr Ave, Itasca, IL 60143, US · [hello@clixo.sh](mailto:hello@clixo.sh)
[Start a build](https://clixo.sh/#contact) · [All services](https://clixo.sh/services) · [Agent guide (llms.txt)](https://clixo.sh/llms.txt)
