Design tokens are the atomic building blocks of a design system. They represent the smallest decisions about color, spacing, typography, and motion, stored as platform-agnostic key-value pairs. When implemented well, they become the single source of truth that bridges the gap between design tools and production code.
But as organizations grow and products multiply, a flat list of tokens quickly becomes unmanageable. Teams need a structured architecture that supports theming, white-labeling, and multi-platform delivery without drowning in complexity. This article explores a proven three-layer approach used by teams at scale.
Why design tokens matter
Every design system eventually faces a consistency crisis. Designers specify one shade of blue, but engineers implement three slightly different variants. A button radius changes in Figma, but the corresponding CSS value stays the same for months. These micro-inconsistencies compound into a fragmented user experience that erodes trust in the product.
Design tokens solve this by externalizing design decisions into a shared, version-controlled format. Instead of hardcoding #1D6EEB throughout your stylesheets, you reference var(--color-primary). When the brand color changes, you update one value and every surface reflects the change instantly.
Design tokens are not just about convenience. They encode the design intent behind every visual decision, making it possible for teams to reason about why a value exists, not just what it is.
The benefits extend beyond consistency. Tokens enable automated testing of visual properties, support dark mode and high-contrast themes through aliasing, and allow non-technical stakeholders to understand and contribute to the design language through a readable vocabulary.
The three-layer architecture
The most resilient token architectures use three distinct layers, each with a clear purpose. This separation of concerns mirrors well-known software patterns and makes it straightforward to modify one aspect of the system without breaking another.
Foundation tokens
Foundation tokens are raw, primitive values with no semantic meaning. They represent the complete palette of options available to the system. Think of them as your design vocabulary: every possible color, every spacing increment, every shadow definition.
/* Foundation tokens — raw values */
--blue-500: #1D6EEB;
--blue-600: #1B69C2;
--gray-100: #F2F4F7;
--gray-900: #101828;
--space-4: 16px;
--space-6: 24px;
Foundation tokens should never be referenced directly in component styles. They exist solely to provide the raw material that brand and semantic tokens draw from. This constraint is critical: it means you can completely swap out a foundation palette without touching any component code.
Brand tokens
Brand tokens map foundation values to product-specific identities. They answer the question: "Which foundation value represents our primary brand color?" This layer is where multi-brand and white-label scenarios are handled.
- colorPrimary500 maps to a specific blue in the foundation layer
- colorSecondary500 maps to a specific orange for accent usage
- Each brand token references a foundation token, never a raw hex value
- Swapping brands means only changing these mappings
Semantic tokens
Semantic tokens are the tokens that components actually consume. They describe the purpose of a value, not its visual appearance. --color-error is semantic; --red-500 is not. This distinction is what makes theming possible: in dark mode, --color-error might resolve to a lighter red for legibility, while --red-500 remains unchanged.
- Define the intent: what does the component need? (e.g., a surface color, a text color, an interactive state)
- Map to brand tokens: connect the intent to a brand-level decision
- Override per theme: dark mode, high contrast, and brand variants each provide their own mappings
- Consume in components: every
var()reference in CSS uses a semantic token
Implementation strategies
Choosing the right format and tooling for your tokens depends on your tech stack, team size, and delivery requirements. Here are the approaches we have seen work well at different scales.
CSS custom properties
For web-first teams, CSS custom properties provide native token support with zero build-step overhead. They cascade naturally, can be scoped to components, and support runtime theming through class-based overrides. The Morpheme design system uses this approach with a root-level declaration block:
:root {
--color-primary: #1D6EEB;
--color-primary-light: #EFF8FF;
--color-error: #F04438;
--shadow-md: 0 4px 8px -2px rgba(16,24,40,0.10),
0 2px 4px -2px rgba(16,24,40,0.06);
}
.theme-dark {
--color-primary: #60A5FA;
--color-primary-light: #1D2939;
--color-error: #FCA5A5;
}
The advantage here is simplicity and browser-native performance. The tradeoff is that CSS custom properties are string-based, which means you lose type safety and cannot perform compile-time validation of token references.
Token transformation pipelines
For multi-platform teams (web, iOS, Android), tools like Style Dictionary or Theo allow you to define tokens in a canonical JSON format and transform them into platform-specific outputs: CSS variables, Swift enums, Kotlin objects, or XML resources. This approach adds build complexity but ensures cross-platform consistency from a single source.
The best token architecture is the one your team will actually maintain. Start with the simplest approach that meets your current needs, and add transformation layers only when multi-platform delivery demands it.
Measuring adoption
A token architecture is only valuable if teams actually use it. Without measurement, you are building infrastructure on faith. Here are the metrics that matter most:
- Token coverage — percentage of hardcoded values replaced by token references across the codebase
- Component adoption — number of product surfaces using design system components versus custom implementations
- Contribution rate — how often product teams propose or submit new tokens and components back to the system
- Theme compliance — whether dark mode, high-contrast, and brand variants render correctly across all surfaces
- Developer satisfaction — quarterly surveys measuring ease of use, documentation quality, and unblocking speed
We recommend running automated linting rules that flag raw hex values, pixel literals, and font-family strings that should be token references. These checks can run in CI pipelines and pull request reviews, catching regressions before they reach production.
Token adoption is a cultural challenge as much as a technical one. Invest in onboarding documentation, pair programming sessions with early adopters, and a responsive support channel. The fastest path to adoption is making the right thing the easy thing: when using a token is simpler than hardcoding a value, teams will adopt naturally.