Every design system eventually arrives at the same bottleneck: someone adds a color variable called blue-500, another person creates primary-button-bg, and six months later the token file is a graveyard of naming collisions and orphaned values. The problem was never the tokens themselves — it was the lack of architecture underneath them.
Design tokens solve one deceptively simple problem: storing design decisions as platform-agnostic data. A color, a spacing unit, a font weight — each becomes a named value that travels from design tools to code without losing meaning along the way. But storing decisions and organizing them are two different challenges entirely.
What design tokens actually solve
A hex code like #F97316 means nothing on its own. It could be a brand accent, a warning indicator, or a hover state. Tokens attach intent to raw values — turning #F97316 into color.accent.primary, which any engineer or designer can read without opening a Figma file.
This matters most at scale. When a single color appears in forty components across three platforms, changing it means updating one token rather than hunting through stylesheets. According to CSS-Tricks, tokens act as the shared contract between design and engineering — a single source of truth that both disciplines reference.
Without that contract, design systems drift. Engineers hard-code values. Designers override them in Figma. The system fractures silently until an audit reveals dozens of off-spec implementations.
The three-tier architecture
Most mature token systems settle on three layers, each with a distinct responsibility. Think of them as levels of abstraction — raw material at the bottom, user-facing decisions at the top.
Tier 1: Primitives
Primitives are the raw palette. Every possible value in your system lives here, named by what it is rather than what it does. Colors follow a scale (gray-100 through gray-900), spacing uses a mathematical progression (space-1 through space-12), and typography lists every available weight and size.
Primitives never appear directly in component code. They exist to feed the next tier.
Tier 2: Semantic tokens
Semantic tokens map primitives to purpose. gray-900 becomes color.text.primary. space-4 becomes spacing.component.gap. The naming shifts from describing the value to describing the role.
This is the tier that enables theming. When dark mode flips color.text.primary from gray-900 to gray-100, every component using that semantic token updates automatically. No component knows or cares which primitive sits behind the name.
Tier 3: Component tokens
Component tokens are optional but powerful for large systems. They reference semantic tokens and scope them to a specific component: button.bg.default, button.bg.hover, button.text.disabled. As Smashing Magazine notes, breaking components into their anatomical parts — label, container, icon, state — reveals exactly which tokens each piece needs.
Component tokens add a layer of indirection. They cost more to maintain, so only introduce them when a component genuinely needs values that diverge from the semantic defaults.
| Tier | Names describe | Example | Changes when |
|---|---|---|---|
| Primitive | The value itself | blue-500, space-4 | Brand palette changes |
| Semantic | The purpose | color.text.primary, spacing.gap | Theme switches |
| Component | The usage | button.bg.hover | Component redesign |
Naming conventions that survive
Naming is where most token systems accumulate debt. A few conventions keep things manageable.
Use a consistent taxonomy: category — property — variant — state. For example, color.bg.surface.hover reads naturally and sorts predictably. According to Smashing Magazine’s naming guide, the best token names are the ones a new team member can guess correctly on the first try.
Avoid encoding platform specifics. ios-padding-large ties a token to one platform — the opposite of what tokens are for. Use spacing.container.lg and let each platform’s build step translate it.
Avoid encoding the value in the name. red-error breaks the moment your error color changes to orange. color.feedback.error survives any palette update.
Good token names read like a sentence: category, then context, then detail. — Derived from naming patterns across major design systems
W3C format vs Tokens Studio
Two formats dominate the token ecosystem right now: the W3C Design Tokens Community Group specification and the Tokens Studio format popularized by the Figma plugin.
The W3C spec defines a JSON structure with explicit $value and $type fields. It aims to be the universal interchange format — tools that read and write W3C tokens should be interoperable without custom transforms.
Tokens Studio uses a similar JSON structure but adds Figma-specific features: token sets, themes as set combinations, and math expressions within values. It’s more expressive for design tool workflows but less portable across the broader toolchain.
| Aspect | W3C spec | Tokens Studio |
|---|---|---|
| Maturity | Draft standard, evolving | Production-used, plugin-driven |
| Tool support | Growing (Style Dictionary, Penpot) | Figma-centric |
| Theming | Not opinionated | Built-in set/theme model |
| Math expressions | Not supported | Supported |
| Portability | High (interchange format) | Medium (needs transforms) |
For new projects in 2026, starting with W3C-compatible structure is the safer bet. Penpot recently shipped native token support using a W3C-aligned format — a signal that the open standard is gaining real tool adoption. You can always layer Tokens Studio on top for Figma-specific workflows while keeping W3C as the canonical source.
When to add a new token
The most common mistake in token management is creating too many. Every token is a maintenance commitment — someone has to name it, document it, and keep it in sync across tools.
A practical threshold: add a new semantic token when three or more components share the same design decision and that decision might change independently. If only one button uses a specific border radius, a component-scoped CSS variable is enough. If that radius appears on cards, modals, and dropdowns, it deserves a semantic token like radius.container.md.
Similarly, resist creating component tokens for every property. Start with semantic tokens only. Promote to component tokens when a specific component needs to override the semantic default in a way that other components should not follow.
The rule of three applies here just like it does in code refactoring: abstract on the third use, not the first.
Conclusion
Token architecture is not about the format you pick or the tool you use — it is about how clearly your naming and layering communicate design intent. Start with primitives as your raw palette, map them to semantic tokens that describe purpose, and only add component tokens when complexity demands it.
Pick one component in your current system — a button or a card — and trace every design value back through the three tiers. If you find hard-coded hex codes or ambiguous names like blue-3, that is where your token architecture needs work first.