Hero image for "Semantic Token Names Feel Principled Right Up Until You Need to Ship"

Semantic Token Names Feel Principled Right Up Until You Need to Ship


Here's the trap: you spend a sprint building a token naming system that reads like a sentence. color-action-primary-bg-hover. Clean. Grammatical. As one practitioner framing the approach puts it, "a token name is a sentence with grammar" — every hyphen-delimited segment answers a different question, and if you reorder them, you change what the sentence means.

That's genuinely good thinking. And it will slow your team down.

Not because the grammar is wrong. Because the grammar is expensive — and at startup scale, the cost arrives before the benefit does.

The Overhead Nobody Budgets For

Semantic naming systems require two things that teams consistently underestimate: upfront taxonomy decisions and ongoing taxonomy enforcement.

The taxonomy problem shows up immediately. Before you can name a token, you have to know which layer it lives in. GitLab's Pajamas system organizes tokens into three categories — constant, semantic, and contextual — where constants are raw values, semantics encode global intent, and contextuals encode component-specific decisions. That's a sensible architecture. It's also a classification decision that has to happen every single time someone adds a token.

The full naming pattern Pajamas documents is: [group].[component].[variant/category].[element].[position].[relationship].[property].[type].[scale].[state]. That's ten possible segments, each with its own rules about when to include it. GitLab is a large, mature engineering organization with dedicated design system infrastructure. They can afford the cognitive overhead of that schema. A four-person frontend team shipping a new product surface every two weeks cannot.

The enforcement problem is slower to arrive but more damaging. Semantic naming only works if everyone applies the grammar consistently. The moment two engineers name tokens differently — one writes button-label-text-filled, another writes button-primary-label-text — you've got a system that looks semantic but behaves like a mess. Both names look plausible. Neither is obviously wrong. The confusion is the point: without shared grammar rules, semantic names create ambiguity faster than descriptive names do, because they promise more precision than they deliver.

When Semantic Names Actually Pay Off

This isn't an argument against semantic tokens. It's an argument about timing.

Semantic naming earns its overhead when you have two specific conditions: multiple surfaces that need to share the same design decisions, and a team large enough that informal coordination breaks down. GitLab's rationale is explicit about this — tokens exist to "synchronize design decisions across design and development tooling" and to "support efforts like color modes by abstracting intent from underlying values." Color mode support is the clearest case. If you need text.color.subtle to resolve to different hex values in light and dark mode without touching component code, semantic indirection is doing real work.

Typography systems show the same pattern. The Type Founders' framing is useful here: tokens describe decisions, styles describe roles. A token like font-weight-emphasis carries meaning that survives a value change — if you update the weight, the token name still tells you what the weight is for. That's the genuine win. But it only matters if the token is referenced in enough places that a single change propagating through the system saves real time.

At early startup scale — one product, one team, one theme — you're paying the taxonomy cost without collecting the propagation benefit.

What to Do Instead (And When to Upgrade)

The practical move is to start with descriptive names that encode just enough intent to be useful, and defer the full semantic layer until you have concrete evidence you need it.

Concretely: name tokens for what they are and where they're used, not for an abstract role hierarchy you haven't built yet. button-bg-hover is worse than color-action-primary-bg-hover in a mature system. It's better than color-action-primary-bg-hover when you're still figuring out whether "action" is even a category your system needs.

The signal that you've outgrown descriptive naming is specific: you find yourself making the same value change in multiple places because tokens don't alias to a shared source, or you're adding a second theme and the names don't generalize. Those are real problems that semantic architecture solves. Ship to them, not ahead of them.

Last week's post on premature semantic layers made the case that token combinations don't explode — semantic layers do, when they're added before the system has enough surface area to justify them. The naming question is the same problem one level up. The grammar is sound. The question is whether your system is complex enough to need a grammar at all.

Most early-stage systems aren't. Build the vocabulary first. The grammar can wait.