In this guide
What you will learn
- The Problem with Literal Names
- Two Layers: Primitives and Semantics
- Why the Two-Layer Approach Wins
- Naming Conventions That Scale
Naming colors sounds trivial until a design system grows and someone has to decide whether a button should use blue, blue-2, primary, or action. Good color naming is one of the quiet foundations of a maintainable system. Poor naming leads to confusion, duplication, and colors that nobody dares to change. This guide covers conventions that scale.
The Problem with Literal Names
The most tempting approach is to name colors after what they look like: blue, light-blue, dark-blue. This works until the day your blue needs to become teal, or marketing rebrands and your blue token now holds a green value. Literal names lie the moment a color changes, and they tell you nothing about where the color should be used.
"A color name should describe its job, not its appearance. The appearance will change; the job usually will not."
Two Layers: Primitives and Semantics
The most durable systems use two layers of naming. The first layer, primitives, names raw values neutrally, often by hue and step: blue-500, gray-100, red-700. These are the actual colors, organized like a paint box. If you need help labeling an unfamiliar hue, a color name finder gives you the closest standard name to use as a starting point.
The second layer, semantic tokens, names colors by purpose and points at primitives: color-primary might reference blue-500, surface-base might reference gray-50, and text-danger might reference red-700. Components only ever use semantic tokens.
Why the Two-Layer Approach Wins
This separation is what makes systems flexible. When you rebrand, you change which primitive each semantic token points to, and every component updates automatically without touching a single component file. When you add dark mode, the same semantic token simply references a different primitive in the dark theme. The components never know or care about the raw value.
Naming Conventions That Scale
A few practical rules keep names consistent as the system grows:
- Use numeric steps (50, 100, 200 ... 900) for primitive scales rather than vague words like
lightanddark, which run out fast. - Name semantics by role:
primary,secondary,surface,border,text, and states likesuccess,warning,danger. - Be consistent with separators and order, for example
category-role-variant, so names are predictable. - Avoid encoding the value in the semantic name.
text-on-primaryis good;white-textis fragile.
Document the Intent
Names are only half the story. A short note beside each semantic token, explaining when to use it, prevents the slow drift where developers pick whatever looks right. A line like "surface-raised: use for cards and elevated panels" removes guesswork and keeps usage consistent across a large team.
Start Simple, Grow Deliberately
You do not need fifty tokens on day one. Begin with a small primitive scale and a handful of semantic tokens that cover your real needs, then expand only when a genuine new use appears. A color system named by purpose, built in two layers, and documented with intent will stay understandable and changeable for years, which is the entire point of a design system.