Design.dev design.dev

Design Systems & Tokens

A complete guide to building scalable design systems with design tokens. Learn how to create, organize, and implement tokens across platforms for consistent, maintainable design.

Introduction

A design system is a collection of reusable components, guided by clear standards, that can be assembled to build applications. Design tokens are the foundational building blocks—the visual design atoms like colors, spacing, and typography that power your design system.

Why Design Systems Matter:

  • Ensure consistency across products and platforms
  • Speed up design and development workflows
  • Create a shared language between design and engineering
  • Make updates and rebranding easier
  • Scale design across teams and products

What Are Design Tokens?

Design tokens are named entities that store visual design attributes. They're platform-agnostic—the same token can generate CSS variables, iOS Swift code, Android XML, and more.

// Token definition (JSON)
{
  "color": {
    "brand": {
      "primary": {
        "value": "#0066ff",
        "type": "color",
        "description": "Primary brand color"
      }
    }
  }
}
/* Generated CSS */
:root {
  --color-brand-primary: #0066ff;
}

/* Usage */
.button {
  background: var(--color-brand-primary);
}
// Generated Swift (iOS)
struct ColorTokens {
  static let colorBrandPrimary = UIColor(hex: "0066ff")
}

Token Categories

Design tokens are typically organized into categories based on their purpose.

Core Token Categories

Category Purpose Examples
Color Brand colors, UI colors, semantic colors primary, secondary, success, error, background
Spacing Margins, padding, gaps xs, sm, md, lg, xl (0.5rem, 1rem, 2rem, etc.)
Typography Font families, sizes, weights, line heights font-family-sans, font-size-body, font-weight-bold
Sizing Width, height, icon sizes icon-sm, icon-md, button-height
Border Border widths, styles, radius border-width-thin, border-radius-sm
Shadow Box shadows, elevation shadow-sm, shadow-md, shadow-lg
Motion Animation durations, easing duration-fast, duration-normal, easing-standard
Z-index Layering order z-dropdown, z-modal, z-tooltip

Naming Conventions

Consistent naming is critical for scalability. Use clear, descriptive names that convey meaning and hierarchy.

Common Naming Patterns

✓ Recommended

Category-Based Naming

/* Pattern: category-property-variant-state */
--color-background-primary
--color-background-secondary
--color-text-primary
--color-text-secondary
--spacing-sm
--spacing-md
--font-size-body
--font-size-heading
✓ Recommended

Scale-Based Naming

/* Numeric or t-shirt scales */
--space-1, --space-2, --space-3
--space-xs, --space-sm, --space-md, --space-lg, --space-xl

/* Color scales */
--gray-50, --gray-100, --gray-200, ... --gray-900
--blue-50, --blue-100, ... --blue-900
✓ Recommended

Semantic Naming

/* Purpose-driven names */
--color-primary
--color-success
--color-warning
--color-error
--button-primary-background
--button-primary-text
--input-border-default
--input-border-focus
✗ Avoid

Non-Descriptive Names

/* Too vague or specific */
--blue         /* Which blue? */
--color1       /* Meaningless */
--big-spacing  /* Imprecise */
--the-blue-on-homepage  /* Too specific */

Naming Best Practices:

  • Use consistent casing (kebab-case for CSS, camelCase for JavaScript)
  • Start with the category for better grouping
  • Use meaningful, not literal names (semantic vs. presentational)
  • Include variants and states when applicable
  • Avoid platform-specific or implementation details

Token Hierarchy

Design tokens typically exist in a three-tier hierarchy: Global → Alias → Component.

Level 1: Global Tokens (Primitives)

Raw values with no context. These are your palette.

--blue-50: #eff6ff --blue-500: #3b82f6 --blue-900: #1e3a8a --space-1: 0.25rem --space-4: 1rem

Level 2: Alias Tokens (Semantic)

Context-aware names that reference global tokens.

--color-primary: var(--blue-500) --color-text: var(--blue-900) --spacing-default: var(--space-4)

Level 3: Component Tokens

Component-specific tokens that reference alias or global tokens.

--button-bg: var(--color-primary) --button-text: white --button-padding: var(--spacing-default)
/* Token hierarchy in practice */

/* Level 1: Global/Primitive tokens */
:root {
  --blue-50: #eff6ff;
  --blue-500: #3b82f6;
  --blue-900: #1e3a8a;
  --space-2: 0.5rem;
  --space-4: 1rem;
}

/* Level 2: Alias/Semantic tokens */
:root {
  --color-primary: var(--blue-500);
  --color-text-primary: var(--blue-900);
  --spacing-sm: var(--space-2);
  --spacing-md: var(--space-4);
}

/* Level 3: Component tokens */
.button {
  --button-bg: var(--color-primary);
  --button-text: white;
  --button-padding: var(--spacing-sm) var(--spacing-md);
  
  background: var(--button-bg);
  color: var(--button-text);
  padding: var(--button-padding);
}

/* This creates a maintainable cascade:
   component → semantic → primitive */

Why Use This Hierarchy?

  • Flexibility: Change a semantic token and all components update
  • Clarity: Each level has a clear purpose
  • Maintainability: Updates happen at the right level
  • Theming: Easy to create theme variants by swapping semantic tokens

Color Tokens

Color tokens are the most common design tokens. Organize them by palette, semantic meaning, and component usage.

Color Scales

Create color scales with consistent steps for flexibility and theming.

blue-50
#eff6ff
blue-100
#dbeafe
blue-200
#bfdbfe
blue-300
#93c5fd
blue-400
#60a5fa
blue-500
#3b82f6
blue-600
#2563eb
blue-700
#1d4ed8
/* Color scale tokens */
:root {
  /* Gray scale */
  --gray-50: #f9fafb;
  --gray-100: #f3f4f6;
  --gray-200: #e5e7eb;
  --gray-300: #d1d5db;
  --gray-400: #9ca3af;
  --gray-500: #6b7280;
  --gray-600: #4b5563;
  --gray-700: #374151;
  --gray-800: #1f2937;
  --gray-900: #111827;
  
  /* Brand color scales */
  --blue-500: #3b82f6;
  --green-500: #10b981;
  --red-500: #ef4444;
  --yellow-500: #f59e0b;
}

Semantic Color Tokens

/* Map scales to semantic meanings */
:root {
  /* Brand colors */
  --color-primary: var(--blue-500);
  --color-primary-hover: var(--blue-600);
  --color-primary-light: var(--blue-100);
  
  /* UI colors */
  --color-background: var(--gray-50);
  --color-surface: white;
  --color-border: var(--gray-200);
  
  /* Text colors */
  --color-text-primary: var(--gray-900);
  --color-text-secondary: var(--gray-600);
  --color-text-tertiary: var(--gray-400);
  
  /* Status colors */
  --color-success: var(--green-500);
  --color-warning: var(--yellow-500);
  --color-error: var(--red-500);
  --color-info: var(--blue-500);
}

Dark Mode Color Tokens

/* Light theme (default) */
:root {
  --color-background: white;
  --color-text: var(--gray-900);
  --color-border: var(--gray-200);
}

/* Dark theme */
:root[data-theme="dark"],
.dark-mode {
  --color-background: var(--gray-900);
  --color-text: var(--gray-50);
  --color-border: var(--gray-700);
}

/* Components automatically adapt */
.card {
  background: var(--color-background);
  color: var(--color-text);
  border: 1px solid var(--color-border);
}

Spacing Tokens

Spacing tokens create rhythm and consistency in your layouts. Use a consistent scale.

Spacing Scale Example

--space-1 (xs)
0.25rem (4px)
--space-2 (sm)
0.5rem (8px)
--space-3 (md)
0.75rem (12px)
--space-4 (lg)
1rem (16px)
--space-6 (xl)
1.5rem (24px)
--space-8 (2xl)
2rem (32px)
--space-12 (3xl)
3rem (48px)
--space-16 (4xl)
4rem (64px)

Common Spacing Systems

/* Option 1: Numeric scale (4px base) */
:root {
  --space-0: 0;
  --space-1: 0.25rem;  /* 4px */
  --space-2: 0.5rem;   /* 8px */
  --space-3: 0.75rem;  /* 12px */
  --space-4: 1rem;     /* 16px */
  --space-5: 1.25rem;  /* 20px */
  --space-6: 1.5rem;   /* 24px */
  --space-8: 2rem;     /* 32px */
  --space-10: 2.5rem;  /* 40px */
  --space-12: 3rem;    /* 48px */
  --space-16: 4rem;    /* 64px */
  --space-20: 5rem;    /* 80px */
  --space-24: 6rem;    /* 96px */
}

/* Option 2: T-shirt sizes */
:root {
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 2rem;
  --space-xl: 4rem;
  --space-2xl: 8rem;
}

/* Option 3: Semantic names */
:root {
  --spacing-tight: 0.5rem;
  --spacing-normal: 1rem;
  --spacing-relaxed: 1.5rem;
  --spacing-loose: 2rem;
}

Using Spacing Tokens

/* In components */
.card {
  padding: var(--space-4);
  margin-bottom: var(--space-6);
  gap: var(--space-3);
}

.button {
  padding: var(--space-2) var(--space-4);
}

.section {
  padding-top: var(--space-12);
  padding-bottom: var(--space-12);
}

/* Spacing utilities */
.p-4 { padding: var(--space-4); }
.m-4 { margin: var(--space-4); }
.gap-4 { gap: var(--space-4); }

Typography Tokens

Typography tokens include font families, sizes, weights, line heights, and letter spacing.

Type Scale

--font-size-xs (0.75rem / 12px)
The quick brown fox jumps over the lazy dog
--font-size-sm (0.875rem / 14px)
The quick brown fox jumps over the lazy dog
--font-size-base (1rem / 16px)
The quick brown fox jumps over the lazy dog
--font-size-lg (1.125rem / 18px)
The quick brown fox jumps over the lazy dog
--font-size-xl (1.25rem / 20px)
The quick brown fox jumps over the lazy dog
--font-size-2xl (1.5rem / 24px)
The quick brown fox jumps over the lazy dog
--font-size-3xl (2rem / 32px)
The quick brown fox jumps over the lazy dog
/* Typography tokens */
:root {
  /* Font families */
  --font-family-sans: system-ui, -apple-system, sans-serif;
  --font-family-serif: Georgia, Cambria, "Times New Roman", serif;
  --font-family-mono: "SF Mono", Monaco, "Cascadia Code", monospace;
  
  /* Font sizes */
  --font-size-xs: 0.75rem;    /* 12px */
  --font-size-sm: 0.875rem;   /* 14px */
  --font-size-base: 1rem;     /* 16px */
  --font-size-lg: 1.125rem;   /* 18px */
  --font-size-xl: 1.25rem;    /* 20px */
  --font-size-2xl: 1.5rem;    /* 24px */
  --font-size-3xl: 2rem;      /* 32px */
  --font-size-4xl: 2.5rem;    /* 40px */
  --font-size-5xl: 3rem;      /* 48px */
  
  /* Font weights */
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  
  /* Line heights */
  --line-height-tight: 1.25;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;
  
  /* Letter spacing */
  --letter-spacing-tight: -0.025em;
  --letter-spacing-normal: 0;
  --letter-spacing-wide: 0.025em;
}

Semantic Typography Tokens

/* Map to semantic uses */
:root {
  /* Body text */
  --text-body-font: var(--font-family-sans);
  --text-body-size: var(--font-size-base);
  --text-body-weight: var(--font-weight-normal);
  --text-body-line-height: var(--line-height-normal);
  
  /* Headings */
  --text-heading-font: var(--font-family-sans);
  --text-heading-weight: var(--font-weight-bold);
  --text-heading-line-height: var(--line-height-tight);
  
  --text-h1-size: var(--font-size-4xl);
  --text-h2-size: var(--font-size-3xl);
  --text-h3-size: var(--font-size-2xl);
  --text-h4-size: var(--font-size-xl);
  
  /* Code */
  --text-code-font: var(--font-family-mono);
  --text-code-size: 0.875em;
}

/* Apply to elements */
body {
  font-family: var(--text-body-font);
  font-size: var(--text-body-size);
  font-weight: var(--text-body-weight);
  line-height: var(--text-body-line-height);
}

h1, h2, h3, h4 {
  font-family: var(--text-heading-font);
  font-weight: var(--text-heading-weight);
  line-height: var(--text-heading-line-height);
}

h1 { font-size: var(--text-h1-size); }
h2 { font-size: var(--text-h2-size); }
h3 { font-size: var(--text-h3-size); }
h4 { font-size: var(--text-h4-size); }

code {
  font-family: var(--text-code-font);
  font-size: var(--text-code-size);
}

Implementation

Design tokens can be implemented in various ways depending on your tech stack and workflow.

CSS Variables (Web)

/* tokens.css */
:root {
  /* Colors */
  --color-primary: #0066ff;
  --color-text: #1a1a1a;
  
  /* Spacing */
  --space-4: 1rem;
  
  /* Typography */
  --font-size-base: 1rem;
}

/* Use in components */
.button {
  background: var(--color-primary);
  padding: var(--space-4);
  font-size: var(--font-size-base);
}

Sass/SCSS Variables

// _tokens.scss
$color-primary: #0066ff;
$color-text: #1a1a1a;
$space-4: 1rem;
$font-size-base: 1rem;

// Use in components
.button {
  background: $color-primary;
  padding: $space-4;
  font-size: $font-size-base;
}

JavaScript/TypeScript

// tokens.js
export const tokens = {
  color: {
    primary: '#0066ff',
    text: '#1a1a1a'
  },
  spacing: {
    '4': '1rem'
  },
  fontSize: {
    base: '1rem'
  }
};

// Use in styled-components
import styled from 'styled-components';
import { tokens } from './tokens';

const Button = styled.button`
  background: ${tokens.color.primary};
  padding: ${tokens.spacing[4]};
  font-size: ${tokens.fontSize.base};
`;

Tailwind CSS Integration

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: '#0066ff',
        text: '#1a1a1a'
      },
      spacing: {
        '4': '1rem'
      },
      fontSize: {
        base: '1rem'
      }
    }
  }
}

JSON Token Format (Style Dictionary)

// tokens.json
{
  "color": {
    "primary": {
      "value": "#0066ff",
      "type": "color"
    },
    "text": {
      "value": "#1a1a1a",
      "type": "color"
    }
  },
  "spacing": {
    "4": {
      "value": "1rem",
      "type": "dimension"
    }
  }
}

Multi-Platform Tokens

Design tokens shine when you need to share design values across multiple platforms. Tools like Style Dictionary can transform a single source of truth into platform-specific formats.

Web (CSS)

:root {
  --color-primary: #0066ff;
}

iOS (Swift)

extension Color {
  static let primary = 
    Color(hex: "0066ff")
}

Android (XML)


  #0066ff

React Native

export const tokens = {
  colorPrimary: '#0066ff'
};

Style Dictionary Example

// config.json
{
  "source": ["tokens/**/*.json"],
  "platforms": {
    "css": {
      "transformGroup": "css",
      "buildPath": "build/css/",
      "files": [{
        "destination": "variables.css",
        "format": "css/variables"
      }]
    },
    "ios": {
      "transformGroup": "ios",
      "buildPath": "build/ios/",
      "files": [{
        "destination": "StyleDictionary.swift",
        "format": "ios-swift/class.swift"
      }]
    },
    "android": {
      "transformGroup": "android",
      "buildPath": "build/android/",
      "files": [{
        "destination": "colors.xml",
        "format": "android/colors"
      }]
    }
  }
}

Benefits of Multi-Platform Tokens:

  • Single source of truth for all platforms
  • Consistent design across web, iOS, Android, etc.
  • Automated transformation reduces errors
  • Updates propagate to all platforms at once

Tools & Workflows

Modern tools help manage, transform, and distribute design tokens across teams and platforms.

Popular Design Token Tools

Style Dictionary

Transform design tokens into any format

Theo (Salesforce)

Design token transformation tool

Figma Tokens

Sync tokens between Figma and code

Tokens Studio

Manage design tokens in Figma

Specify

Extract and sync design tokens

Knapsack

Design system platform with tokens

Workflow Example

# 1. Define tokens in JSON
# tokens/colors.json

# 2. Build with Style Dictionary
npm run build-tokens

# 3. Generated outputs:
# - build/css/variables.css
# - build/ios/StyleDictionary.swift
# - build/android/colors.xml

# 4. Commit and distribute
git commit -m "Update design tokens"
npm publish

Design-to-Code Workflow

Modern Token Workflow:

  1. Design: Create tokens in Figma using Tokens Studio plugin
  2. Export: Export tokens as JSON from Figma
  3. Transform: Use Style Dictionary to generate platform files
  4. Distribute: Publish as npm package or include in repos
  5. Consume: Import tokens in web, iOS, Android apps
  6. Update: Changes in Figma propagate through the pipeline

Best Practices

Follow these best practices to create maintainable, scalable design token systems.

1. Use a Consistent Naming Convention

/* Good: Clear hierarchy and meaning */
--color-text-primary
--color-text-secondary
--color-background-primary
--spacing-component-padding
--font-size-heading-large

/* Bad: Inconsistent and unclear */
--primaryText
--bg_color
--Space-2
--large-heading

2. Separate Primitive and Semantic Tokens

/* Primitive tokens (raw values) */
--blue-500: #3b82f6;
--space-4: 1rem;

/* Semantic tokens (meaning) */
--color-primary: var(--blue-500);
--button-padding: var(--space-4);

/* This makes theming and updates easier */

3. Document Your Tokens

{
  "color": {
    "brand": {
      "primary": {
        "value": "#0066ff",
        "type": "color",
        "description": "Primary brand color used for main CTAs and links",
        "wcag": {
          "aa": "Pass on white background",
          "aaa": "Fail on white background"
        }
      }
    }
  }
}

4. Version Your Token Library

// package.json
{
  "name": "@company/design-tokens",
  "version": "2.1.0",
  "description": "Design tokens for Company products",
  "files": ["build/"]
}

5. Test Token Changes

Testing Strategies:

  • Visual regression testing for token updates
  • Contrast ratio testing for color tokens
  • Accessibility testing (WCAG compliance)
  • Cross-platform testing before deployment
  • Validate token JSON schema

6. Avoid Hard-Coded Values

/* Bad: Hard-coded values */
.button {
  background: #0066ff;
  padding: 16px;
  font-size: 14px;
}

/* Good: Use tokens */
.button {
  background: var(--color-primary);
  padding: var(--space-4);
  font-size: var(--font-size-sm);
}

7. Plan for Theming

/* Structure tokens to support themes */
:root {
  --color-background: white;
  --color-text: black;
}

[data-theme="dark"] {
  --color-background: black;
  --color-text: white;
}

/* Components work with any theme */
.card {
  background: var(--color-background);
  color: var(--color-text);
}

8. Keep It Simple Initially

Start Small: Begin with the essentials and expand as needed:

  • Core colors (brand, text, background)
  • Basic spacing scale (4-8 values)
  • Essential typography (sizes, weights)
  • Add more as patterns emerge in your designs

Common Pitfalls to Avoid:

  • ❌ Creating too many tokens too early
  • ❌ Using literal names (--blue) instead of semantic (--primary)
  • ❌ Skipping documentation
  • ❌ Not versioning your tokens
  • ❌ Mixing implementation details with design tokens
  • ❌ Inconsistent naming conventions
  • ❌ Forgetting about accessibility