Skip to content

Journal

Design systems

How I learned to name design tokens, by naming them badly first

My first big token file fought me within two weeks. The naming pattern I use now, with before-and-after examples you can copy.

The token name color/action/primary/hover with red brackets naming each part: category, element, role, state.

About two weeks into my first big token file, it was fighting me.

It had grown into a three-tier hierarchy, primitives, semantic tokens and component tokens, with 615 tokens in it. Some aliases pointed at tokens that didn’t exist. My radius scale had a medium that was smaller than small. I had built a simpler system beside it, so I compared the two, kept the simple one and archived the rest.

What I know about naming came from that trial and error, from YouTube tutorials, and from reading. Recently, I studied the W3C Design Tokens Format Module (2025.10) alongside Figma’s documentation on variable modes. Three lessons stuck: name the job, not the colour; give every name the same parts in the same order; and keep modes out of the name.

A token name should say what it’s for

Say a team names its main button colour blue-500 and uses it on buttons, links, tabs and badges. Then the brand moves to teal. Now either blue-500 holds a teal value, or someone rebinds every one of them by hand. Either way, the name has stopped telling the truth.

A role name doesn’t have that problem. color/action/primary says what the colour is for. When the brand changes, the value changes and the name is still right.

Raw names still belong in the palette. blue-500 is a fine name for a swatch. It’s a bad name to put on a button.

Two tokens used in four places; when the brand turns teal, blue-500 mislabels it and color/action/primary still fits.
When the brand colour changes, a raw name starts to lie. A role name stays true.

Give every name the same parts, in the same order

Good names read from general to specific: the category, then the element, then the role, then the state.

  • color/action/primary/hover

  • color/text/secondary

  • border/control/default

  • color/surface/raised

Nathan Curtis’s guide to naming tokens splits a name into a namespace, an object, a base (category, concept and property) and modifiers (variant, state, scale and mode). Start with his simplest rule, and use only the levels a name needs.

Two smaller rules help.

  • One word, one meaning. If “primary” means the main action in one group, don’t use it for the main brand colour in another.

  • Scales should sort. radius/s, radius/m and radius/l should get bigger in that order. Mine didn’t, once.

Three cards with corner radii labelled small, medium and large; in the top row medium is smaller than small, marked in red.
A scale’s names promise an order. Check that the values keep it.

One rule comes from the format itself. In the W3C format, a name can’t contain a dot or curly braces, because those mark paths and aliases: {color.text.primary} points at a token. In Figma, a slash in a variable name creates a group.

Where do modes go?

Keep them out of the name. surface-light and surface-dark look tidy until you add a high-contrast theme, then a compact density, and the list doubles each time.

Make the mode a switch instead: one token, color/surface/raised, with a value for Light and a value for Dark. In Figma, modes belong to a variable collection, and each collection has one set of modes. So if you have two switches that change on their own, like colour theme and screen size, give each its own collection. A frame can then be Dark and Mobile at once, with no token called dark-mobile-anything.

Eight mode-named versions of one token beside three tokens that each hold a Light and a Dark value.
Every mode in a name doubles the list. As a switch, it adds one value per token.

Two tiers first, a third when you need it

Most token guides show three tiers. My archived file had all three.

Start with two: primitives, the raw palette named by value, and semantic tokens, named by job. Bind components to the semantic tokens. Add a component token when several components need the same decision and no semantic name covers it. Curtis suggests keeping component tokens local and promoting one to a shared token once around three components use it.

One name in Figma and in code

The last lesson is about the hand-off. If a developer sees color/text/primary in Figma’s Dev Mode and var(--color-text-primary) in their CSS, nobody has to translate between the two. Generate the CSS names from the Figma export with a small script, so nobody retypes them.

This, not that

Instead of

Try

Why

blue-500 on a button

color/action/primary

The role survives a rebrand

surface-dark

color/surface/raised, with a Dark mode

The mode is a switch, not part of the name

button-primary-bg-hover on day one

color/action/primary/hover

Add component tokens once several components share a decision

grey-text-light

color/text/secondary

Says where it goes, not how it looks

radius/m smaller than radius/s

Values that grow in name order

Scales should sort

How I’d start a token file now

  1. Write the palette as primitives, named by value: blue-500, grey-450.

  2. Write semantic tokens by job: text, surface, border, action, status.

  3. Give each mode switch its own collection: theme, screen size, motion.

  4. Bind components to semantic tokens only.

  5. Generate the code names from the export.

  6. Add component tokens last, when several components share a decision.

I used this naming in the design system I built for KFintech, from the colour roles to the CSS. (The colour values behind those names had to pass contrast checks too; that part is in What I learned reading WCAG 2.0, 2.1 and 2.2 side by side.)

Related case study: the KFintech design system case study.

Let’s work together

Open to new work and collaborations. Email is the quickest way to reach me.

Resume (PDF, opens in a new tab)
hi@amandeepux.com
Based in Hyderabad, India.© 2026 Amandeep Singh. Designed and built in Framer by me.Privacy