Design SystemsTokens

Token architecture: the decisions that matter before you write a line of code

The naming and structure of your token system determines whether it survives past the first redesign. Here's what actually matters.

Most design system teams discover tokens the hard way. You build components first, define colors per-component as you go, and six months later you're staring at 400 color values across 70 components trying to figure out how to make dark mode work without rewriting everything.

The architecture decisions that matter for tokens aren't about naming conventions, though those matter too. They're about what a token actually represents.

Primitives are not the same as semantics

The most consequential structural decision is whether you separate raw values from their usage. This is the primitive/semantic split, and skipping it is the most common expensive mistake.

A primitive says what a value is: blue-600 is #0369a1. A semantic token says what it means: color/text/link is the color used for interactive text links. The semantic token references the primitive. The primitive never references anything.

This matters because when you decide to change your link color globally, or when you add dark mode and need link colors to be different at night, you change one semantic token. One. Every component that referenced color/text/link updates automatically. No hunting, no missing instances, no the-table-component-that-everyone-forgot.

Without the split, changing anything requires finding every hardcoded instance. Which you will do incompletely. Which is why dark mode implementations so often have 30 components that updated and 8 that didn't.

The naming decision you can't take back

Once you ship a token name to production, exposed to code, referenced in documentation, used by a dozen engineers, you cannot change it without a migration. Token names are a public API. Treat them like one from day one.

A few things I've learned about naming:

Slash-separated paths age better than camelCase. color/bg/primary is readable in design tool variable pickers, survives more transformation pipelines, and doesn't create confusion between token names and CSS property names in code.

Usage-based semantic names outlive appearance-based ones. color/text/link tells you its usage. color/brand-blue-text tells you what it looks like, which becomes a lie when you rebrand. Tokens named by usage survive redesigns. Tokens named by appearance become technical debt within two years.

Don't optimize for brevity too early. btn-bg feels efficient until you have 12 component categories and realize you can't tell the tokens apart in a dropdown. Verbose names are annoying to type. Ambiguous names are expensive to untangle.

Modes are scoped to collections

This is the part Figma makes confusing. When you add a Dark mode to a collection, every variable in that collection has to define a dark-mode value. That's fine for your color collection. It's a mess for your spacing collection, which doesn't change in dark mode.

The right structure: colors go in one collection with Light and Dark modes. Spacing goes in a separate collection with a single Value mode. Typography scales go in their own collection. Each collection has exactly the modes it needs and no others.

If your spacing tokens have a Dark mode, something has gone wrong in the architecture. Spacing doesn't change in the dark. Giving it a mode creates busywork and invites mistakes.

The component token question

There's an ongoing debate about whether to have component-level tokens like button/bg/primary and input/border/default, or to go straight from semantic tokens into component code.

My current view: component tokens make sense when the same semantic value is used differently in different components and you want to be able to change one without affecting the other. They don't make sense as wrappers that just re-alias a semantic token with no additional meaning. button/bg/primary: color/bg/primary is noise. A token that does nothing but point to another token adds a layer of indirection without adding information.

Before creating a component token, ask whether this represents a genuine design decision scoped to this component, or whether it's just a namespace you're adding for tidiness. If it's the latter, skip it.

The question to ask before naming anything

What decision does this token represent?

Not what value does it hold. What design decision. color/text/secondary represents the decision about what color secondary text should be, globally, across the whole system. That's a real decision with real implications. It belongs in a token.

If you can't articulate the design decision a token represents, it's probably not a token. It's a variable you're trying to make feel principled.

Start with the decisions. Name the decisions. Build components that reference the decisions. That's the order that survives your second redesign. And your first design system engineer leaving the team.

Greg Sargent
Greg SargentDirector of Design Systems, Spring Health

I write about design systems, accessibility, and the way AI is changing how we build software.

Published November 21, 2025

Be the first to rate this article.