Design

Design Tokens:
The Single Source of Truth for Visual Style

Design tokens are the atomic units of a design system — named variables for color, spacing, typography, and motion that connect design tools to production code. Without them, every team speaks a different dialect of the same visual language, and consistency erodes with every sprint.

The Problem They Solve

Before design tokens, visual consistency was enforced by convention and documentation. Designers maintained a style guide; developers transcribed values from Figma; the two drifted apart over time. The primary button's blue in the style guide might be #1A6CF6. In the CSS it might be #1a6ef6 in one component and #1a6cf5 in another — close enough that no one notices until you put them side by side.

Design tokens solve this by making the value a single named entity that both design tools and code reference from the same source. The color is no longer a hex value you look up — it's color.interactive.primary, and the hex is defined exactly once, in one place, and any downstream change propagates everywhere.

A design token is not just a variable. It's a contract between design and engineering — a shared name for a shared value.

The Three-Layer Architecture

Well-structured token systems use three layers that progressively add semantic meaning:

Primitive

Raw values with no semantic meaning. color.blue.500 = #1A6CF6, space.4 = 16px, font.size.base = 1rem. These are the vocabulary of the system — atoms that have no opinion about where they're used. You should almost never reference primitive tokens directly in component code.

Semantic

Values with intent. color.interactive.primary = color.blue.500, color.background.surface = color.neutral.100. Semantic tokens reference primitives and add meaning: this is what "primary interactive color" means in terms of the raw palette. These are what component code should reference.

Component

Component-specific tokens that reference semantic tokens. button.primary.background = color.interactive.primary. Optional for most systems but valuable when a component has specific override behavior or when multiple brands need to configure component appearances independently.

Dark Mode and Theming

The primary practical benefit of semantic tokens becomes obvious when implementing dark mode or multi-brand theming. Without tokens, dark mode requires auditing every hardcoded color value in the codebase. With semantic tokens, dark mode is a different value for each semantic token — the component code changes nothing.

/* Light theme */ :root { --color-background-primary: #ffffff; --color-text-primary: #0a0a0a; --color-interactive-accent: #1A6CF6; } /* Dark theme — same tokens, different values */ [data-theme="dark"] { --color-background-primary: #0a0a0a; --color-text-primary: #f0f0f0; --color-interactive-accent: #4d94ff; } /* Component references tokens — never changes for theme */ .button-primary { background: var(--color-interactive-accent); color: var(--color-background-primary); }

Naming Conventions That Scale

Token names should describe intent, not appearance. color.feedback.error is better than color.red — the first is stable as the visual language evolves; the second breaks if you ever change error states to orange for accessibility reasons. The name should answer "what is this for?" not "what does it look like?"

Avoid encoding the value in the name (spacing.16px), encoding hierarchy positions that may change (color.gray.lightest — what happens when you add a lighter gray?), and creating tokens that are too specific to a single component (sidebar.icon.hover.background — that belongs in the component layer, not the semantic layer).

Connecting Design Tools to Code

The promise of design tokens — a single source of truth — only holds if design tools and code reference the same token file. In practice, this is maintained through two mechanisms: design tool plugins (Figma's Variables feature, Tokens Studio) that export token values to JSON, and build tools (Style Dictionary, Theo) that transform that JSON into platform-specific formats: CSS custom properties, Swift constants, Kotlin strings, JavaScript objects.

A token update in Figma flows through CI/CD into a PR that updates the CSS. Designers and engineers look at the same token names and know they refer to the same values. This is the end state worth working toward — but it requires upfront agreement on the token schema and consistent discipline in using tokens rather than hardcoded values on both sides of the handoff.