Deep Dive: Token Naming & Hierarchy
Why Naming Matters
Token names are API design. They're the interface between design decisions and implementation—the contract that designers, developers, and tooling all depend on. A poorly named token creates confusion, duplication, and technical debt. A well-named token communicates intent, enables discovery, and scales gracefully.
Unlike code variables that can be refactored with IDE tooling, token names propagate across design tools, documentation, CSS output, and TypeScript types. Renaming a token is a breaking change that ripples through the entire system. This makes getting names right from the start essential.
The Naming Formula
Every token name follows a consistent pattern that encodes its layer, category, and purpose:
[layer].[category].[subcategory].[variant].[state]
Examples:
core.color.palette.neutral.600
semantic.color.foreground.primary
semantic.components.button.primary.background
semantic.spacing.gap.gridLayer Prefix (Required)
Every token starts with its layer prefix. This immediately communicates where the token lives in the hierarchy and what it can reference:
| Prefix | Purpose | Can Reference |
|---|---|---|
core. | Raw primitives with no semantic meaning | Nothing (leaf nodes with raw values) |
semantic. | Purpose-driven roles and aliases | core.* or other semantic.* tokens |
semantic.components. | UI-specific bindings | semantic.* or core.* tokens |
Category (Required)
The category groups tokens by their fundamental type. This enables filtering, tooling, and mental models:
| Category | What It Contains | Examples |
|---|---|---|
color | All color values | palette, foreground, background, border, status |
spacing | Spatial dimensions | size scale, gap, padding, margin |
typography | Text-related values | family, weight, ramp, lineHeight, letterSpacing |
motion | Animation properties | duration, easing, delay, stagger |
shape | Geometric properties | radius, border |
elevation | Depth and layering | shadow, depth, level |
components | Component-specific tokens | button, input, card, badge |
Subcategory (Context-Dependent)
Subcategories provide additional grouping within a category. Their structure depends on the layer:
// Core: Subcategory describes the value type
core.color.palette.neutral.600 // "palette" = color scale
core.color.mode.dark // "mode" = theme base colors
core.spacing.size.04 // "size" = spacing scale
// Semantic: Subcategory describes the role
semantic.color.foreground.primary // "foreground" = text/icon colors
semantic.color.background.danger // "background" = surface colors
semantic.color.border.subtle // "border" = boundary colors
semantic.color.status.success // "status" = feedback colorsVariant and State (Optional)
Variants describe visual weight or emphasis. States describe interactive conditions:
// Variants (visual weight)
semantic.components.button.primary.background
semantic.components.button.secondary.background
semantic.components.button.danger.background
// States (interactive conditions)
semantic.components.button.primary.background.hover
semantic.components.button.primary.background.active
semantic.components.button.primary.background.disabledNaming Principles
1. Describe Purpose, Not Implementation
Token names should communicate what something is for, not what it looks like. This enables theming and evolution without breaking names.
// BAD: Describes implementation
semantic.color.blue500
semantic.color.grayText
semantic.spacing.16px
// GOOD: Describes purpose
semantic.color.foreground.link
semantic.color.foreground.secondary
semantic.spacing.gap.grid2. Use Nouns for Tokens, Verbs for Utilities
Tokens represent values (nouns). Utilities and functions represent actions (verbs). This distinction keeps the mental model clear.
// Tokens (nouns) - represent values
semantic.color.foreground.primary
semantic.motion.duration.short
semantic.elevation.shadow.raised
// Utilities (verbs) - represent actions
getTokenValue('semantic.color.foreground.primary')
resolveReference('{core.color.palette.blue.500}')
validateToken(tokenDefinition)3. Maintain Consistent Depth
Tokens at the same conceptual level should have the same depth. Avoid skipping hierarchy levels or creating inconsistent structures.
// BAD: Inconsistent depth
semantic.color.primary // 3 levels
semantic.color.foreground.primary // 4 levels
semantic.color.background.surface.raised // 5 levels
// GOOD: Consistent depth within category
semantic.color.foreground.primary
semantic.color.foreground.secondary
semantic.color.foreground.tertiary
semantic.color.background.primary
semantic.color.background.secondary
semantic.color.background.raised4. Use American English Spelling
For consistency across the codebase, use American English spelling. This aligns with CSS property names and most programming conventions.
// BAD: British spelling
semantic.color.grey.500
semantic.color.foreground.colour
// GOOD: American spelling
semantic.color.gray.500
semantic.color.foreground.color5. Prefer Explicit Over Abbreviated
Clarity beats brevity. Abbreviated names save a few characters but cost discoverability and understanding.
// BAD: Abbreviated
semantic.clr.fg.prim
semantic.typ.wt.bd
semantic.spc.sz.04
// GOOD: Explicit
semantic.color.foreground.primary
semantic.typography.weight.bold
semantic.spacing.size.04Hierarchy Patterns
Core Token Hierarchy
Core tokens organize raw values by their type. The hierarchy reflects the nature of the value, not its usage:
core/
├── color/
│ ├── palette/
│ │ ├── neutral/ # 100-800 grayscale
│ │ ├── red/ # 100-800 red scale
│ │ ├── blue/ # 100-800 blue scale
│ │ └── ...
│ ├── mode/
│ │ ├── light # Base light color
│ │ ├── dark # Base dark color
│ │ └── transparent # Transparent
│ └── datavis/ # Chart colors
│
├── spacing/
│ └── size/
│ ├── 00 # 0
│ ├── 01 # 1px
│ ├── 02 # 2px
│ └── ... # up to 10 (64px)
│
├── typography/
│ ├── family/ # Font families
│ ├── weight/ # Font weights
│ ├── ramp/ # Size scale
│ ├── lineHeight/ # Line height ratios
│ └── letterSpacing/ # Letter spacing values
│
├── motion/
│ ├── duration/ # Timing values
│ ├── easing/ # Easing curves
│ └── delay/ # Delay values
│
├── shape/
│ ├── radius/ # Border radii
│ └── border/ # Border styles
│
└── elevation/
├── shadow/ # Box shadows
└── depth/ # Z-index layersSemantic Token Hierarchy
Semantic tokens organize values by their purpose in the UI. The hierarchy reflects usage patterns and design decisions:
semantic/
├── color/
│ ├── foreground/
│ │ ├── primary # Main text
│ │ ├── secondary # Supporting text
│ │ ├── tertiary # Subtle text
│ │ ├── link # Link text
│ │ └── inverse # Text on dark backgrounds
│ ├── background/
│ │ ├── primary # Main surface
│ │ ├── secondary # Alternate surface
│ │ ├── brand # Brand-colored surface
│ │ └── danger # Error/warning surface
│ ├── border/
│ │ ├── default # Standard borders
│ │ ├── subtle # Light borders
│ │ └── strong # Emphasized borders
│ └── status/
│ ├── info # Informational
│ ├── success # Positive
│ ├── warning # Caution
│ └── danger # Error/critical
│
├── spacing/
│ ├── gap/ # Flex/grid gaps
│ ├── padding/ # Internal spacing
│ └── margin/ # External spacing
│
├── components/
│ ├── button/
│ │ ├── primary/
│ │ │ ├── background
│ │ │ ├── foreground
│ │ │ └── border
│ │ ├── secondary/
│ │ └── danger/
│ ├── input/
│ ├── card/
│ └── ...Pitfalls to Avoid
1. Color Names in Semantic Tokens
Never use color names in semantic tokens. This couples the name to a specific implementation and breaks when themes change.
// BAD: Color name in semantic token
semantic.color.blueButton
semantic.color.redError
semantic.color.greenSuccess
// GOOD: Purpose-based names
semantic.color.background.brand
semantic.color.status.danger
semantic.color.status.success2. Size Values in Names
Avoid embedding specific values in token names. Use relative terms or scale positions instead.
// BAD: Values in names
semantic.spacing.16px
semantic.typography.fontSize14
semantic.motion.duration200ms
// GOOD: Relative or scale-based names
semantic.spacing.size.04
semantic.typography.size.body
semantic.motion.duration.short3. Inconsistent Pluralization
Be consistent with singular vs plural. Generally, use singular for categories and plural for collections.
// BAD: Inconsistent pluralization
semantic.colors.foreground.primary
semantic.color.backgrounds.primary
semantic.component.button.primary
// GOOD: Consistent (singular categories)
semantic.color.foreground.primary
semantic.color.background.primary
semantic.components.button.primary4. Overloaded Names
Each token should have one clear purpose. Avoid names that could apply to multiple contexts.
// BAD: Ambiguous names
semantic.color.primary // Primary what? Text? Background?
semantic.spacing.default // Default for what context?
semantic.border.main // Main border color? Width? Style?
// GOOD: Specific names
semantic.color.foreground.primary
semantic.spacing.gap.grid
semantic.color.border.default5. Skipping Hierarchy Levels
Don't skip levels in the hierarchy. This creates inconsistent paths and breaks tooling expectations.
// BAD: Skipped levels
semantic.primary // Missing category
semantic.color.primary // Missing subcategory
semantic.components.background // Missing component name
// GOOD: Complete hierarchy
semantic.color.foreground.primary
semantic.color.background.primary
semantic.components.button.primary.backgroundNaming for Discoverability
Good naming enables discovery through autocomplete, search, and browsing. Consider how developers will find tokens:
Autocomplete-Friendly
Names should narrow down progressively. Start broad (layer), then category, then specifics:
// Typing "semantic.color." shows:
semantic.color.foreground.*
semantic.color.background.*
semantic.color.border.*
semantic.color.status.*
// Typing "semantic.color.foreground." shows:
semantic.color.foreground.primary
semantic.color.foreground.secondary
semantic.color.foreground.tertiary
semantic.color.foreground.linkSearch-Friendly
Names should be searchable by common terms. Include the most likely search terms in the path:
// Searching "button" finds:
semantic.components.button.*
// Searching "error" or "danger" finds:
semantic.color.status.danger
semantic.color.background.danger
semantic.components.button.danger.*Summary
- Layer prefix is required—
core.,semantic., orsemantic.components. - Describe purpose, not implementation—
foreground.primarynotgray600 - Use nouns for tokens, verbs for utilities
- Maintain consistent depth within categories
- Prefer explicit over abbreviated names
- Avoid color names, size values, and ambiguous terms in semantic tokens
Well-named tokens are an investment that pays dividends in maintainability, discoverability, and team velocity. Take the time to get names right—your future self and your team will thank you.
Next Steps
With naming conventions established, explore how tokens enable multi-brand theming, how the resolver module handles context-aware resolution, and how schema validation enforces these conventions automatically.