Back to Design Systems
Topic 2 of 8

Design Tokens

Define and manage colors, typography, spacing, and other design decisions as tokens

What Are Design Tokens?

Design tokens are the smallest pieces of a design system—named values that represent design decisions. Instead of hardcoding #3B82F6 everywhere, you use color-primary. This abstraction makes your design system maintainable, themeable, and consistent.

🎨 Types of Design Tokens

Colors

Primary, secondary, semantic (error, success)

Typography

Font families, sizes, weights, line heights

Spacing

Margins, padding, gaps (4px, 8px, 16px...)

Sizing

Component sizes, icon sizes, border radius

Effects

Shadows, blurs, opacity values

Motion

Durations, easing curves, delays

Token Hierarchy

Tokens are typically organized in layers from abstract to specific:

/* Level 1: Primitive/Global Tokens - Raw values */
--color-blue-500: #3B82F6;
--color-blue-600: #2563EB;
--spacing-4: 16px;
--spacing-8: 32px;

/* Level 2: Semantic/Alias Tokens - Purpose-based */
--color-primary: var(--color-blue-500);
--color-primary-hover: var(--color-blue-600);
--color-error: var(--color-red-500);
--spacing-component: var(--spacing-4);

/* Level 3: Component Tokens - Component-specific */
--button-background: var(--color-primary);
--button-background-hover: var(--color-primary-hover);
--button-padding: var(--spacing-component);
--card-border-radius: var(--radius-lg);

Defining Tokens in JSON

Many teams define tokens in JSON format for easy transformation:

// tokens/colors.json
{
  "color": {
    "primitive": {
      "blue": {
        "50": { "value": "#EFF6FF" },
        "100": { "value": "#DBEAFE" },
        "500": { "value": "#3B82F6" },
        "600": { "value": "#2563EB" },
        "900": { "value": "#1E3A8A" }
      },
      "gray": {
        "50": { "value": "#F9FAFB" },
        "900": { "value": "#111827" }
      }
    },
    "semantic": {
      "primary": { "value": "{color.primitive.blue.500}" },
      "primary-hover": { "value": "{color.primitive.blue.600}" },
      "background": { "value": "{color.primitive.gray.50}" },
      "text": { "value": "{color.primitive.gray.900}" }
    }
  }
}

// tokens/spacing.json
{
  "spacing": {
    "0": { "value": "0px" },
    "1": { "value": "4px" },
    "2": { "value": "8px" },
    "3": { "value": "12px" },
    "4": { "value": "16px" },
    "6": { "value": "24px" },
    "8": { "value": "32px" }
  }
}

CSS Custom Properties (Variables)

/* tokens.css */
:root {
  /* Colors */
  --color-primary: #3B82F6;
  --color-primary-hover: #2563EB;
  --color-secondary: #6366F1;
  --color-success: #10B981;
  --color-error: #EF4444;
  --color-warning: #F59E0B;
  
  /* Typography */
  --font-sans: 'Inter', system-ui, sans-serif;
  --font-mono: 'Fira Code', monospace;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  
  /* Spacing */
  --spacing-1: 0.25rem;
  --spacing-2: 0.5rem;
  --spacing-3: 0.75rem;
  --spacing-4: 1rem;
  --spacing-6: 1.5rem;
  --spacing-8: 2rem;
  
  /* Border Radius */
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-full: 9999px;
  
  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
}

/* Using tokens in components */
.button {
  background-color: var(--color-primary);
  padding: var(--spacing-2) var(--spacing-4);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  box-shadow: var(--shadow-sm);
}

.button:hover {
  background-color: var(--color-primary-hover);
}

Token Transformation with Style Dictionary

Style Dictionary by Amazon transforms tokens from JSON to any format (CSS, SCSS, JS, iOS, Android).

# Install Style Dictionary
npm install style-dictionary

# config.json
{
  "source": ["tokens/**/*.json"],
  "platforms": {
    "css": {
      "transformGroup": "css",
      "buildPath": "build/css/",
      "files": [{
        "destination": "variables.css",
        "format": "css/variables"
      }]
    },
    "js": {
      "transformGroup": "js",
      "buildPath": "build/js/",
      "files": [{
        "destination": "tokens.js",
        "format": "javascript/es6"
      }]
    },
    "scss": {
      "transformGroup": "scss",
      "buildPath": "build/scss/",
      "files": [{
        "destination": "_variables.scss",
        "format": "scss/variables"
      }]
    }
  }
}

# Build tokens
npx style-dictionary build

Output example in CSS:

/* build/css/variables.css */
:root {
  --color-primary: #3B82F6;
  --color-primary-hover: #2563EB;
  --spacing-4: 16px;
  /* ... more tokens */
}

Tokens in Tailwind CSS

// tailwind.config.js
module.exports = {
  theme: {
    colors: {
      primary: {
        DEFAULT: 'var(--color-primary)',
        hover: 'var(--color-primary-hover)',
        light: 'var(--color-primary-light)',
      },
      secondary: 'var(--color-secondary)',
      success: 'var(--color-success)',
      error: 'var(--color-error)',
    },
    spacing: {
      0: '0',
      1: 'var(--spacing-1)',
      2: 'var(--spacing-2)',
      3: 'var(--spacing-3)',
      4: 'var(--spacing-4)',
      6: 'var(--spacing-6)',
      8: 'var(--spacing-8)',
    },
    borderRadius: {
      sm: 'var(--radius-sm)',
      md: 'var(--radius-md)',
      lg: 'var(--radius-lg)',
      full: 'var(--radius-full)',
    },
    fontFamily: {
      sans: 'var(--font-sans)',
      mono: 'var(--font-mono)',
    },
  },
}

// Usage in JSX

💡 Best Practices

  • • Use semantic names (color-primary) not descriptive names (color-blue)
  • • Create a token hierarchy: primitive → semantic → component
  • • Store tokens in a single source of truth (JSON, Figma)
  • • Use tools like Style Dictionary for multi-platform output
  • • Document what each token is for and when to use it
  • • Version your tokens and communicate changes to teams