- Web Design
- Engineering
A design system is only as good as its weakest handoff, and the weakest handoff is almost always "here's a hex code, use it wherever." Tokens exist to close that gap.
Primitives vs. semantic tokens
The pattern that holds up longest is a two-layer one: raw primitives (a color scale, a spacing scale), and semantic tokens that reference them by purpose rather than value.
:root {
/* primitive */
--color-gray-900: #111827;
/* semantic — what components actually use */
--color-text: var(--color-gray-900);
}Components should only ever reach for the semantic layer. When a rebrand or a dark mode comes along, you repoint the mapping once, in one file, and every component that used --color-text updates without a single line of component code changing.
Sizing tokens, not just color
The same idea applies to spacing and type — a component sets its own scale once, then sizes everything inside it relative to that, so nudging one value rescales the whole component predictably instead of requiring a find-and-replace across dozens of files.
Where this breaks down
Tokens fail when there are too many of them, named too specifically — --button-primary-hover-dark-mode-border is not a token, it's a variable pretending to be one. Keep the vocabulary small and the purpose obvious, and resist adding a new token until something is genuinely reused in a second place.
If you're mid-rebuild and want a second pair of eyes on your token structure, we're happy to help.
