NewMCP Apps — interactive section cards now render inside your AI chatRead the changelog
Engineering

Design tokens as the only source of truth

A token file that designers edit and engineers ignore is not a source of truth. It is documentation with extra steps.

DR3 min readUpdated
On this page 5 sections

In short

Design tokens only work as a single source of truth when the same file is consumed at build time by every surface — design tool, website, product UI and documentation. If any surface hardcodes a value that a token already defines, the token system has become advisory, and drift is a matter of time rather than risk.

Key takeaways

  • A token is only a source of truth if no surface can render without reading it.
  • Ship tokens as build-time artefacts, not as a document people are asked to follow.
  • Semantic aliases (surface-raised) outlive raw scales (grey-100) because they survive rebrands.
  • Lint for hardcoded values in CI — the rule is cheap and it catches drift on the day it happens.

Most token systems fail the same way. The file exists, it is well named, it is even generated from the design tool. And then a marketing page ships with a hex code typed straight into a stylesheet, because it was faster, and nobody notices for five months.

What makes a token authoritative rather than advisory?#

One property: it is impossible to render the surface without reading the token file. Not discouraged, not code-reviewed against — impossible. Every other definition of "source of truth" degrades into a naming convention that holds for as long as the team is small enough to remember it.

Three layers, in this order#

  • Primitive — the raw value. orange-500 is #FD8800 and means nothing else.
  • Semantic — the intent. action-primary points at orange-500 today.
  • Component — the binding. button-bg-primary points at action-primary.

Components never reference primitives. That single rule is what makes a rebrand a one-line change instead of a quarter of work, because the semantic layer absorbs the change and nothing below it has to move.

css
/* primitive → semantic → component */
:root{
  --orange-500:#FD8800;              /* primitive: a value  */
  --action-primary:var(--orange-500);/* semantic:  a meaning */
}
.btn-primary{
  background:var(--action-primary);  /* component: a binding */
}

Where do token systems actually drift?#

Not in the product UI, which is usually well policed. Drift starts in three predictable places: marketing pages built under deadline, email templates that cannot use CSS variables, and anything a third-party embed styles for you.

SurfaceTypical driftFix
Marketing pagesHardcoded hex under deadlineCI lint on raw colour values
Transactional emailNo CSS var supportBuild-time inline from the same JSON
Third-party embedsVendor stylesheet winsWrap in a scoped token bridge
Docs siteSeparate theme fileConsume the published token package

Lint the thing you care about#

A regex that fails the build on a raw hex outside the primitive file takes an afternoon to write and removes an entire category of drift permanently. It will annoy people in week one and be invisible by week four.

Publishing is the part people skip#

Tokens that live in a repo one team can push to are a shared file, not a package. Version them, changelog them, and let consumers upgrade deliberately. A token change that silently repaints a downstream product is worse than no token system, because it teaches everyone downstream to pin and stop upgrading.

Related questions

What is a design token?

A design token is a named, machine-readable value that stores one design decision — a colour, a spacing step, a radius, a type size. Because it is data rather than a documented convention, every surface can read the same value at build time.

Should components reference primitive tokens directly?

No. Components should reference semantic tokens, which in turn point at primitives. That indirection is what lets you rebrand by repointing the semantic layer without touching a single component.

How do you stop design token drift?

Lint for raw values in CI, publish tokens as a versioned package rather than a shared file, and make sure no surface can render without reading the token source — including marketing pages and email.

How many tokens is too many?

There is no fixed ceiling, but if contributors cannot find an existing token in under a minute they will create a duplicate. Searchable naming matters more than total count.

Comments

No comments yet — be the first to share a thought.

Leave a comment

Your email is never shown. Comments are reviewed before they appear.

Links in comments are marked ugc nofollow.

Keep reading

All articles