Field Notes
All posts

Design tokens that last

Name tokens for their purpose, not their value, and a rebrand becomes an afternoon instead of a quarter.

What a token is

A design token is a named decision: a color, a spacing step, a font size, a radius, a shadow. Instead of writing a hex value in fifty places, components refer to a name, and the name resolves to a value in one place. Change the value, and every component follows.

Name for purpose, not appearance

The most common mistake is naming tokens after what they look like. A token called blue-500 used for primary buttons, links and focus rings ties three different purposes to one color. When the brand moves from blue to green, blue-500 either becomes a lie or every usage must be found and renamed.

A layered approach avoids this:

  • Primitive tokens describe the raw palette: blue-500, gray-100, space-4.
  • Semantic tokens describe purpose: color-action-primary, color-text-muted, space-stack-md.
  • Component tokens, where needed, describe a specific part: button-primary-background.

Components use semantic or component tokens. Only the semantic layer refers to primitives.

Theming falls out naturally

With semantic tokens in place, dark mode is a second mapping from the same semantic names to different primitives. color-surface resolves to white in one theme and near-black in the other. Components do not need to know which theme is active.

Keep the scale small

A spacing scale with thirty steps is not a system; it is a list of every value anyone ever used. Seven to ten steps cover nearly every need and make layouts feel consistent. The same applies to type sizes, radii and shadows. When a designer needs a value between two steps, that is a conversation about whether the scale is right, not a reason to add a one-off.

One source, many outputs

Store tokens in a format that can generate CSS custom properties, platform values for native apps, and documentation from the same source. Tools exist for this, but even a small script that reads a JSON file and writes CSS is enough to start.

Document the intent

For each semantic token, write one line about when to use it and when not to. "Muted text: secondary information such as timestamps and captions. Not for disabled controls" prevents the slow drift where every gray gets used for every purpose.

Audit for leaks

Periodically search the codebase for raw color values and pixel spacing that bypass tokens. Each one is a place a future theme change will miss. A lint rule that flags them keeps the system honest without anyone having to remember.