Designing Token Systems
Token-Based Design System Framework
Create a three-tier token hierarchy in Figma Variables:
Primitive → Semantic → Component
#2563EB → color.brand.primary → button.background.default
Set up collections: Primitives, Semantic, Component with modes for light, dark, brand-a, brand-b.
Progress:
- Define primitive tokens (raw values)
- Create semantic tokens (purpose-based)
- Build component tokens (contextual)
- Configure Figma Variables with modes
- Set up Token Studio plugin
- Export to Style Dictionary
- Sync with development via GitHub
1. Primitive Tokens
Raw design values without context:
Colors:
primitive.blue.50: #EFF6FF
primitive.blue.500: #3B82F6
primitive.blue.900: #1E3A8A
primitive.gray.100: #F3F4F6
primitive.gray.900: #111827
Spacing:
primitive.space.1: 4px
primitive.space.4: 16px
primitive.space.8: 32px
Typography:
primitive.font.size.sm: 14px
primitive.font.size.lg: 18px
primitive.font.family.sans: "Inter"
2. Semantic Tokens
Purpose-driven, reference primitives:
Color System:
color.background.primary: primitive.gray.50
color.background.inverse: primitive.gray.900
color.text.primary: primitive.gray.900
color.text.inverse: primitive.gray.50
color.brand.primary: primitive.blue.500
color.brand.secondary: primitive.blue.100
color.feedback.success: primitive.green.500
color.feedback.error: primitive.red.500
Spacing System:
space.component.xs: primitive.space.1
space.component.sm: primitive.space.2
space.layout.section: primitive.space.12
3. Component Tokens
Contextual references to semantic tokens:
button.background.primary.default: color.brand.primary
button.background.primary.hover: color.brand.600
button.background.secondary.default: color.background.primary
button.text.primary.default: color.text.inverse
button.padding.horizontal: space.component.md
button.padding.vertical: space.component.sm
4. Figma Variables Setup
Collections Structure:
Primitives(no modes - static values)Semantic(modes: light, dark, brand-a, brand-b)Component(modes: light, dark, brand-a, brand-b)
Mode Configuration:
Semantic Collection:
├── light (default)
├── dark
├── brand-a
└── brand-b
Component Collection:
├── light (default)
├── dark
├── brand-a
└── brand-b
5. Token Studio Integration
Plugin Setup:
- Install Token Studio for Figma
- Connect to GitHub repository
- Configure JSON structure:
JSON{ "primitive": { "color": { "blue": { "500": { "value": "#3B82F6", "type": "color" } } } }, "semantic": { "color": { "brand": { "primary": { "value": "{primitive.color.blue.500}", "type": "color" } } } } }
Example 1: Multi-Brand Button System Input: Need buttons that work across 3 different brand identities Output:
// Primitive
primitive.blue.500: #3B82F6
primitive.red.500: #EF4444
primitive.purple.500: #8B5CF6
// Semantic (varies by brand mode)
color.brand.primary:
- brand-a: primitive.blue.500
- brand-b: primitive.red.500
- brand-c: primitive.purple.500
// Component
button.background.primary.default: color.brand.primary
Example 2: Dark Mode Typography Input: Text tokens that adapt to light/dark themes Output:
// Semantic tokens with mode variants
color.text.primary:
- light: primitive.gray.900
- dark: primitive.gray.50
color.text.secondary:
- light: primitive.gray.600
- dark: primitive.gray.400
// Component usage
card.text.heading: color.text.primary
card.text.body: color.text.secondary
Structure Pattern
[tier].[category].[subcategory].[variant].[state]
Tier Prefixes
primitive.- Raw valuescolor.,space.,typography.- Semantic (no prefix for primary semantic)[component].- Component-specific (button, card, input)
Categories
Color: background, text, border, brand, feedback
Space: component, layout, radius
Typography: font, text
Variants & States
Variants: primary, secondary, tertiary
States: default, hover, active, disabled, focus
Sizes: xs, sm, md, lg, xl
Multi-Brand Scaling
// Brand-agnostic semantic layer
color.brand.primary
color.brand.secondary
color.brand.accent
// Mode-specific values
brand-nike: color.brand.primary → primitive.orange.500
brand-adidas: color.brand.primary → primitive.black.900
brand-puma: color.brand.primary → primitive.blue.600
Token Hierarchy:
- Primitives never reference other tokens
- Semantic tokens only reference primitives
- Component tokens only reference semantic tokens
Naming Consistency:
- Use consistent vocabulary:
primary/secondary/tertiary, notmain/sub/extra - Follow size scales:
xs/sm/md/lg/xlor numeric1/2/4/8/12 - Group related tokens:
button.background.*,button.text.*
Mode Management:
- Start with light/dark, add brand modes later
- Use same token names across all modes
- Test mode switching in Figma prototypes
Documentation:
- Comment complex token relationships
- Maintain usage guidelines for each token
- Create Figma examples for each component token
Avoid deep nesting: color.background.card.header.primary.default is too complex
Don't skip semantic layer: Components shouldn't directly reference primitives
Inconsistent naming: Mixing btn and button, bg and background
Mode confusion: Different token names across light/dark modes
Primitive pollution: Adding contextual meaning to primitive tokens (primitive.blue.brand instead of color.brand.primary)
Component coupling: Making tokens too specific (login-button-background vs button.background.primary)