August 14, 2026 / Web Design
Design token naming conventions for small teams
Design token naming conventions for small teams
Two designers ship a button on a Tuesday. By Friday, the same button is named three different ways in three files. One file says color/blue/500, another says button/primary/bg, and a third says brand/cta/hover. None of them are wrong, and that is exactly the problem. The team did not have a shared rule, so each person made a reasonable local decision that does not connect to the others.
That is the moment most small teams hit when they start using design tokens. The tokens themselves are usually fine. The names are not. Design token naming conventions for small teams exist to remove exactly this kind of quiet drift, so a token you picked in January still means the same thing in August, and so a new designer can guess a token name before they ask anyone.
This article is a working guide for product teams of roughly two to ten people. It covers the practical conventions that survive contact with real work: category-first structure, the difference between role names and raw values, when to add tiers, how to handle themes, and the small set of habits that keep a token system from collapsing under its own weight.
What a design token actually names
A design token is a named, reusable value. It can hold a color, a spacing size, a radius, a font size, a motion duration, a shadow definition, or even a typography stack. The name is the contract. The value is the implementation. The name is what humans, design tools, and code all need to agree on.
Because the name is the contract, a token is only as useful as the system that names it. Two teams can store #3366FF in a file and still disagree about what it is called. One calls it blue/500, another calls it action/primary. Both files hold the same color, but the first is describing the value, the second is describing the job. Small teams that confuse those two layers end up with files full of tokens that cannot be searched, themed, or reasoned about.
A solid naming convention answers three questions for every token:
- What kind of thing is it? Color, space, type, motion, radius, shadow, or z-index.
- What is its job in the interface? Background, border, text, surface, accent, danger.
- Where does it sit in the scale or tier? A primitive value, a semantic alias, or a component-specific override.
Once those three answers are clear, the name is mostly mechanical. A token like color/surface/default reads as a color, used on surfaces, for the default state. A token like space/stack/md reads as spacing, for stacked layouts, at the medium step. The reader does not need the JSON open to picture the value.
Why small teams need conventions more than big ones
Large teams can absorb inconsistency through process. They have a design system team, a contribution review, a governance meeting, and a tooling layer that masks bad names. Small teams usually have none of that. They have two or three designers, one or two engineers, and a shared folder of Figma styles. Naming drift in that environment is not a theoretical risk. It is what happens by the third sprint.
Small teams also tend to wear more hats. The person who picks a color on Monday may be the person who refactors the CSS on Thursday. Conventions protect that single contributor from themselves. If the rule is clear, the same person can make consistent decisions on different days, in different moods, under different time pressure.
There is a second reason conventions matter more for small teams. Big systems can hide their mistakes. A token called misc/teal/3 in a 4,000-token file is easy to ignore. In a 60-token file, that one bad name takes up 1.5 percent of the system. It is felt. It gets copy-pasted, then duplicated, then quietly becomes a standard. Catching bad names early is much cheaper than cleaning them up after a year of reuse.
The two layers small teams should keep separate
The single most useful rule in token naming is also the simplest: keep the raw scale and the job-based aliases apart. Most confusion in small-team token files comes from mixing them in a single flat list.
Layer 1: the primitive scale
The primitive scale is the raw material. It is a small, well-named set of values that exist on their own, with no opinion about how they will be used. For colors, that means a hue ladder like blue/50, blue/100, blue/500, blue/900. For space, it means a step scale like space/0, space/100, space/200, space/400, space/800. The primitive scale looks like a design palette or a type scale. It is a controlled vocabulary of values.
Layer 2: the semantic aliases
Semantic aliases are the tokens the rest of the team should reach for. They describe a job, not a value. color/text/primary, color/surface/raised, color/border/subtle, space/stack/sm. Each alias points at a primitive. When the primitive changes, every alias that references it updates with it. When the product decides that “subtle border” should be lighter, you change the alias, not every component that uses it.
The benefit of these two layers is that they answer different questions. A designer asks, “What color should this heading be?” and reaches for a semantic token. A design system maintainer asks, “What is our blue 500 used for?” and looks at the primitive. The two roles have two different tools, and the names do not collide.
A category-first naming structure that holds up
Most small teams do well with a strict category-first path. Every token name starts with its kind, then its role, then any qualifier. The slash is a convention borrowed from tools like Style Dictionary and from design tool exports, and it works because it groups naturally.
Color tokens
Colors are the most common token type and the easiest to mess up. A workable color path looks like this:
color/primitive/blue/500for raw scale values.color/semantic/text/primaryfor foreground text in body content.color/semantic/text/mutedfor secondary text and helper copy.color/semantic/surface/defaultfor the base background of a panel or page.color/semantic/surface/raisedfor cards and elevated containers.color/semantic/border/subtlefor hairlines and dividers.color/semantic/action/primaryfor primary buttons and key actions.color/semantic/action/primary-hoverfor the hover state of the same.color/semantic/feedback/dangerfor errors and destructive states.
The first segment, color, is the type. The second segment, primitive or semantic, is the layer. Everything after that is the job. There is no need to encode the hex value in the name. If someone needs the hex, the file is right there.
Spacing, radius, and motion tokens
Non-color tokens follow the same pattern, with a type-first segment and a role-based qualifier. A few examples that read well in Figma, in CSS variables, and in code:
space/stack/xs,space/stack/sm,space/stack/md,space/stack/lgfor vertical rhythm between stacked blocks.space/inline/sm,space/inline/mdfor horizontal rhythm between related elements.space/inset/sm,space/inset/mdfor padding inside a container.radius/sm,radius/md,radius/lg,radius/pillfor corner radii.motion/duration/fast,motion/duration/base,motion/duration/slowfor transition timing.motion/easing/standard,motion/easing/emphasizedfor the easing curves themselves.
Notice the difference between space/stack/md and space/inset/md. The numeric step is the same, but the role is different. A stack token is the gap between siblings. An inset token is the padding inside a single element. Naming them separately lets a future refactor change one without touching the other.
Typography tokens
Typography is where small teams often try to do too much. Keep the names narrow:
type/size/xs,type/size/sm,type/size/md,type/size/lg,type/size/xl,type/size/2xlfor the size scale.type/weight/regular,type/weight/medium,type/weight/boldfor the weights actually used.type/line/tight,type/line/normal,type/line/loosefor line height.type/family/sans,type/family/monofor the actual font families.type/role/heading,type/role/body,type/role/captionas semantic aliases that combine size, weight, and line height into a single concept.
The type/role/* aliases are the ones designers should pick from most of the time. The primitive scale stays in the file for cases where a designer genuinely needs a step that is not a named role yet.
How to choose the segments: a decision table
When a small team is not sure which segment a token belongs in, this table helps. Read it as a quick reference, not as a strict rulebook.
| If the token is used for | Type segment | Layer segment | Role segment | Example |
|---|---|---|---|---|
| A raw blue shade from the palette | color | primitive | blue/500 | color/primitive/blue/500 |
| Body text color | color | semantic | text/primary | color/semantic/text/primary |
| Card background | color | semantic | surface/raised | color/semantic/surface/raised |
| Primary button hover | color | semantic | action/primary-hover | color/semantic/action/primary-hover |
| Vertical gap between cards | space | semantic | stack/md | space/stack/md |
| Padding inside a button | space | semantic | inset/sm | space/inset/sm |
| Default corner radius | radius | semantic | md | radius/md |
| Transition timing | motion | semantic | duration/base | motion/duration/base |
| Heading text style | type | semantic | role/heading | type/role/heading |
The most common mistake in this table is skipping the role segment and going straight to a value. color/blue/500 is fine as a primitive. color/button/bg is fine as a component token. color/blue/500 applied directly to a button is not a token, it is a leak. The role segment is what stops that leak.
Naming tiers most small teams actually need
You will see references to three-tier or even four-tier token architectures. Most small teams do not need all of them. Pick the smallest set that survives a year of real work.
Tier 1: primitive tokens
Raw values. Color scales, spacing scales, type sizes, motion curves. These rarely change once the palette is set, and they almost never get referenced directly in product code. Treat them as the kitchen pantry.
Tier 2: semantic tokens
Job-based aliases. color/semantic/text/primary, space/stack/md. These are what designers and engineers reach for ninety percent of the time. Most of your naming convention lives here.
Tier 3: component tokens (only when needed)
Component tokens exist for cases where a specific component needs a value that does not fit a shared semantic role. A date picker’s selected day background, a chart’s grid line color, a drag handle’s hit color. These are written as component/date-picker/selected-bg and point at a semantic token underneath. They are the smallest tier and the most fragile. Use them sparingly, and document why each one exists.
| Tier | Audience | Example name | References |
|---|---|---|---|
| Primitive | Design system maintainers | color/primitive/blue/500 |
A raw value |
| Semantic | Designers and engineers | color/semantic/action/primary |
One primitive token |
| Component | Component owners | component/button/primary-bg |
One semantic token |
If your team is small, stop at two tiers until a specific component proves it needs a third. Three tiers feels tidy in a slide deck and exhausting in a real file.
Rules that prevent the most common naming bugs
Conventions fail in predictable ways. The list below covers the bugs that show up again and again in small-team token files, with a short rule for each.
- Do not encode the value in the name.
color/blue-500forces a rename every time the shade changes. Name the job instead. - Do not mix scales and roles in the same path. Either
color/primitive/blue/500orcolor/semantic/action/primary, nevercolor/blue/action/primary. - Keep modifiers at the end.
color/semantic/text/primary-hoverreads cleanly.color/semantic/hover-text-primarydoes not. - Prefer lowercase, hyphen-free segments.
color/semantic/surface/raisedis easier to read in code thanColor/Semantic/Surface/Raised. - Use the same word for the same idea. Pick “muted” or “secondary” for less prominent text and use it everywhere. Mixing
muted,subtle, andsecondaryfor similar roles makes the system feel bigger than it is. - Avoid abbreviations.
bg,fg,txtare familiar but they save a few characters and cost a lot of clarity for new contributors. - Do not name tokens after components unless the token is a component token. A spacing scale named
space/card-gapbreaks the moment a non-card element needs the same value.
These rules are small, but together they are what makes a token file scannable. The goal is that a designer who has never seen the file can predict the name of a token they need before they open it.
How to name states, variants, and themes
The interesting naming problems usually sit one level below the simple case. States, variants, and themes each have their own trap.
States
States are the variations a single role goes through: default, hover, active, focus, disabled, selected. The convention is to put the state at the end of the path so that the role stays constant and only the suffix changes. color/semantic/action/primary becomes color/semantic/action/primary-hover, ...-active, ...-disabled. This keeps hover and active next to each other in any file browser that sorts alphabetically, which makes state coverage easy to audit.
Focus deserves special care. Focus styles are often a combination of a color and a ring or outline. Many small teams encode focus as a single combined token, like color/semantic/focus/ring, rather than splitting it across color and stroke. The combined approach reads better in audit and maps cleanly to CSS outline properties.
Variants
Variants are larger jumps inside one role. A button has variants for size and tone. A surface has variants for elevation. Treat variants the same way you treat states, with a stable prefix and a changing suffix. radius/sm, radius/md, radius/lg are variants of the same concept. type/role/heading and type/role/heading-emphasized are variants of the same role. The naming rule is the same: keep the prefix stable, vary the suffix.
Themes
Themes are where the two-layer model really earns its keep. With primitives and semantics separated, dark mode is mostly a remap. Each semantic token keeps the same name and points at a different primitive under the dark theme. color/semantic/text/primary in light mode points to a near-black primitive. In dark mode, the same name points to a near-white primitive. The components and the code do not change. The names do not change. Only the mapping changes.
The naming rule for themes is that theme names should never appear inside semantic paths. If you see color/semantic/dark/text/primary, the theme has leaked into the layer that is supposed to be theme-agnostic. Push the theme switch down into the mapping file instead.
A small, opinionated starter file
Most small teams do not need more than fifty tokens to get to a useful first version. The file below is a realistic starting point. It is not a complete system, but it covers color, space, radius, motion, and type for a typical product surface, and it follows the rules in this article.
| Category | Token name | Role |
|---|---|---|
| Color primitive | color/primitive/blue/500 |
Brand blue at the 500 step |
| Color primitive | color/primitive/neutral/900 |
Near-black text primitive |
| Color semantic | color/semantic/text/primary |
Default body text |
| Color semantic | color/semantic/text/muted |
Helper and secondary text |
| Color semantic | color/semantic/surface/default |
Base panel and page background |
| Color semantic | color/semantic/surface/raised |
Card and elevated container |
| Color semantic | color/semantic/border/subtle |
Hairline and divider |
| Color semantic | color/semantic/action/primary |
Primary button background |
| Color semantic | color/semantic/action/primary-hover |
Primary button hover state |
| Color semantic | color/semantic/feedback/danger |
Error and destructive states |
| Space | space/stack/sm |
Default vertical gap between siblings |
| Space | space/stack/md |
Looser vertical gap for sections |
| Space | space/inset/sm |
Compact padding inside small components |
| Space | space/inset/md |
Default padding inside standard containers |
| Radius | radius/md |
Default corner radius for most surfaces |
| Radius | radius/pill |
Fully rounded control |
| Motion | motion/duration/base |
Default transition duration |
| Motion | motion/easing/standard |
Default easing curve |
| Type | type/role/heading |
Default heading style |
| Type | type/role/body |
Default body style |
A starter file like this is small enough to maintain by hand and big enough to carry a product through its first year. The names follow the same rules in every category, which is what makes the file feel coherent rather than improvised.
How to roll out a convention without slowing the team down
A naming convention that nobody uses is just a wish. The rollout matters as much as the rules.
- Start with the rules, not the file. Before anyone touches tokens, write a one-page reference that lists the type segments, the layer segments, the role vocabulary, and a handful of examples. The reference is the contract.
- Pick a single source of truth. For most small teams that is a Figma file with variables, or a Style Dictionary project in a small repo. Pick one. Two parallel sources will drift within a quarter.
- Migrate the tokens that get used. Do not try to rename every style on day one. Rename the tokens that show up in real screens first, then sweep the rest.
- Add a linter or a review checklist. A short PR-style checklist that asks “is this a primitive or a semantic token, and is the role segment correct” catches more bugs than a long governance document.
- Document exceptions inline. When a token breaks the convention, leave a short comment in the file explaining why. Most conventions fail because the exceptions are invisible.
Rollout is where most token projects stall. The mistake is to treat the naming rules as a design exercise and the rollout as an afterthought. For small teams the rollout is the design exercise. The rules only matter to the extent that they reach the file.
Common tradeoffs and how to think about them
Conventions always come with tradeoffs. Naming a token color/semantic/text/primary is clearer for humans but adds a layer of indirection in the code. Naming it color/primitive/neutral/900 is faster to wire up but harder to theme. The honest answer is to pick the tradeoff that matches your team’s reality, not the one that matches a textbook.
If your product is single-theme and the team is two people, you can lean more on primitives and use fewer semantic aliases. You will save time on day one and pay for it the first time you need a dark mode. If your product is multi-theme from day one, invest in the semantic layer early, because the cost of building it later is a rename across every component.
There is also a tradeoff between consistency and speed. A strict rule like “every color token must include the word semantic or primitive” slows down quick experiments. A loose rule speeds up prototypes but lets bad names in. The middle path is to be strict in the production file and loose in a separate scratch file. Many small teams keep a single “scratch” Figma file or branch where the rules are relaxed, and only migrate the survivors into the canonical token file.
How this connects to the rest of your design system work
Token naming does not exist in isolation. It is one of the first decisions a small team makes about how its design system is going to behave, and the rules you set here tend to echo through the rest of the system. The same kind of category-first thinking that organizes a token file is what keeps a component library scannable and a documentation site navigable.
Token naming also shows up indirectly in website strategy work, because a clean token file is what lets a marketing site and a product app share visual rules without sharing code. When the names are stable, a redesign becomes a remap instead of a rewrite.
Frequently asked questions
How many tokens does a small team actually need at launch?
Most small teams can launch with somewhere between forty and eighty tokens. A useful first version covers one neutral color scale, one brand color scale, a spacing scale of five to seven steps, two or three radius steps, two motion durations, and a type role for body and heading. You can add tokens as real screens need them, but you should not ship with fewer than this, because the system will not have enough surface area to enforce the rules yet.
Should the focus keyword “design token naming conventions for small teams” drive a flat list or a tiered file?
For most small teams a two-tier file is the right starting point. A flat list works until you need a dark theme or a brand refresh, and then the lack of layers forces a rename. A two-tier file, with primitives and semantic aliases, handles both without renaming anything in product code. Add a third tier only when a specific component proves it needs a component-specific token.
What is the difference between a semantic token and a component token?
A semantic token describes a job that many components share, like color/semantic/text/primary. A component token is scoped to one component, like component/date-picker/selected-bg. Semantic tokens are the shared vocabulary. Component tokens are the exceptions. If a value is only used by one component, it can be a component token. If the same job shows up in three components, it should be a semantic token.
Do we need to support dark mode from day one?
No, but the naming convention should not block it. If you keep primitives and semantics in separate layers, dark mode becomes a remap of the semantic layer to different primitives. The names do not change, the code does not change. If you skip the semantic layer and reach for primitives directly, dark mode becomes a search-and-replace inside every component, and that is a much more expensive change.
What is the safest way to rename a token that is already in use?
Never rename in place. Add the new name as a new token, point it at the same value, migrate every reference to the new name in a single sweep, and only then remove the old token. A two-step migration costs an afternoon. A single rename across a live codebase costs a week and usually leaves a few stragglers.
How do we handle tokens contributed by people who are not on the core design team?
Use a short review checklist, not a long document. The checklist should ask three things: is this a primitive or a semantic token, is the role segment one of the agreed words, and is there an existing token that already does the same job. If the answer to the third question is yes, the contribution should reuse the existing token rather than add a new one.
Should we use a tool like Style Dictionary from day one?
It depends on how the team is set up. If both design and engineering are using the tokens on day one, a tool like Style Dictionary is worth the small setup cost because it gives both sides a single source of truth. If the tokens are only being used in Figma for a few months, a plain Figma variable file is enough and the tool can be introduced later. The naming rules do not change either way.
What is the most common naming mistake on small teams?
Mixing roles and values in the same path. A token called color/blue-500/button-bg describes both the value and the job, which means it cannot be themed and cannot be reused by anything that is not a button. Splitting the value into a primitive and the job into a semantic alias fixes almost every naming problem a small team runs into.
How do we keep token names stable as the product grows?
Treat the role vocabulary as a contract and the values as a flexible layer under it. The roles, like text/primary, surface/raised, action/primary, are what components and code depend on. The primitives that those roles point at can change without forcing a rename. That separation is what keeps names stable over time.
Useful next steps
If you are starting from scratch, write the one-page reference first. List the type segments, the layer names, the role vocabulary, and ten example tokens that follow the rules. Share it with the people who will actually use the tokens, and revise it once based on their feedback. Then build the file, migrate the tokens that are already in use, and add a short review checklist to the contribution path. The naming convention will not be perfect on day one, and that is fine. The point is that by week three, the file is readable, by month three it is auditable, and by year one it is the reason a redesign takes a week instead of a quarter.