HandoffPro

Design Tokens: The Complete Guide for Developers

·19 min read

TLDR

Design tokens are design decisions stored as data. They represent values like colors (#3B82F6), spacing (16px), and typography (Inter 16px/24px) in a platform-agnostic format (JSON, YAML) that can be transformed into CSS variables, iOS Swift constants, or Android XML resources. Tokens provide a single source of truth for design systems, enabling design changes to propagate across all platforms from a single update.

Key takeaways:

  • Design tokens eliminate hard-coded values and enable theme changes from a single source
  • Two-layer architecture (primitive + semantic tokens) provides flexibility and maintainability
  • JSON format is the industry standard, with W3C working on an official specification
  • Style Dictionary transforms JSON tokens into platform-specific outputs (CSS, iOS, Android)
  • CSS variables are the most common web implementation, enabling runtime theming
  • Multi-platform token strategies enable iOS, Android, and web to share a single token source

What Are Design Tokens?

If you've ever had to update a brand color across a codebase—searching hundreds of files for #3B82F6 and manually replacing every instance—you already understand the problem design tokens solve.

Design tokens are design decisions stored as data. Instead of hard-coding values like color: #3B82F6 or padding: 16px throughout your code, you define these values once in a structured format (typically JSON) and reference them by name.

Think of tokens as variables for design, but with a critical difference: tokens are platform-agnostic. A single JSON token file can generate CSS variables for web, Swift constants for iOS, and XML resources for Android. One source of truth, multiple outputs.

Here's a simple token file showing the core concept:

{
  "color": {
    "brand": {
      "primary": { "value": "#3B82F6" },
      "secondary": { "value": "#1E3A8A" }
    },
    "text": {
      "primary": { "value": "#0F172A" },
      "secondary": { "value": "#64748B" }
    }
  },
  "spacing": {
    "xs": { "value": "4px" },
    "sm": { "value": "8px" },
    "md": { "value": "16px" },
    "lg": { "value": "24px" },
    "xl": { "value": "32px" }
  },
  "typography": {
    "fontFamily": {
      "base": { "value": "Inter, system-ui, sans-serif" },
      "mono": { "value": "JetBrains Mono, monospace" }
    },
    "fontSize": {
      "sm": { "value": "14px" },
      "base": { "value": "16px" },
      "lg": { "value": "18px" },
      "xl": { "value": "24px" }
    }
  }
}

This JSON file becomes the foundation of your design system. Change color.brand.primary from #3B82F6 to #EF4444, run your build process, and every button, link, and icon that uses the primary color updates instantly across all platforms.

Why Design Tokens Matter

Before design tokens, managing design systems meant find-and-replace nightmares, platform drift, and manual synchronization between design tools and code.

The Problem: Hard-Coded Values

In a traditional codebase without tokens, you might have #3B82F6 (your brand blue) scattered across dozens or hundreds of files:

/* button.css */
.button-primary { background: #3B82F6; }
 
/* link.css */
.link { color: #3B82F6; }
 
/* badge.css */
.badge-info { border-color: #3B82F6; }

Now imagine your brand changes to #EF4444 (red). You need to:

  1. Search every file for #3B82F6
  2. Verify each instance is actually the brand color (not a coincidental match)
  3. Manually replace each instance
  4. Repeat for iOS codebase
  5. Repeat for Android codebase
  6. Update design files in Figma

This process takes hours or days and introduces errors. Developers miss instances, designs drift from implementation, and platform teams work from different specifications.

The Solution: Single Source of Truth

With design tokens, the same brand change takes minutes:

  1. Update color.brand.primary in your token JSON file
  2. Run your build process (Style Dictionary, custom script)
  3. All platforms update automatically

73% of developers report wasting time on design inconsistencies and manual specification updates. Design tokens eliminate this waste by centralizing design decisions in a single, version-controlled file.

For teams building across web, iOS, and Android, tokens provide even greater value. Read our multi-platform design tokens guide to learn how companies like Salesforce and Shopify maintain consistency across all platforms from a single token source.

Token Types

Design tokens cover every visual aspect of your interface. Here are the most common token categories:

Color Tokens

Color tokens typically include both palette tokens (raw color values) and semantic tokens (contextual mappings).

Palette tokens define your complete color scale:

{
  "color": {
    "blue": {
      "50": { "value": "#EFF6FF" },
      "500": { "value": "#3B82F6" },
      "900": { "value": "#1E3A8A" }
    },
    "gray": {
      "50": { "value": "#F8FAFC" },
      "500": { "value": "#64748B" },
      "900": { "value": "#0F172A" }
    }
  }
}

Semantic tokens assign meaning:

{
  "color": {
    "brand": {
      "primary": { "value": "{color.blue.500}" },
      "secondary": { "value": "{color.blue.900}" }
    },
    "text": {
      "primary": { "value": "{color.gray.900}" },
      "secondary": { "value": "{color.gray.500}" }
    }
  }
}

Notice the {color.blue.500} reference syntax—this is token aliasing, where semantic tokens reference primitive tokens. When you change the palette, semantic tokens automatically update.

Typography Tokens

Typography tokens define font families, sizes, weights, line heights, and letter spacing:

{
  "typography": {
    "fontFamily": {
      "base": { "value": "Inter, system-ui, sans-serif" },
      "heading": { "value": "Lexend, system-ui, sans-serif" },
      "mono": { "value": "JetBrains Mono, Consolas, monospace" }
    },
    "fontSize": {
      "xs": { "value": "12px" },
      "sm": { "value": "14px" },
      "base": { "value": "16px" },
      "lg": { "value": "18px" },
      "xl": { "value": "24px" },
      "2xl": { "value": "32px" }
    },
    "fontWeight": {
      "normal": { "value": "400" },
      "medium": { "value": "500" },
      "semibold": { "value": "600" },
      "bold": { "value": "700" }
    },
    "lineHeight": {
      "tight": { "value": "1.25" },
      "base": { "value": "1.5" },
      "relaxed": { "value": "1.75" }
    }
  }
}

Spacing Tokens

Spacing tokens define padding, margin, and gap values. Most systems use a 4px or 8px base unit:

{
  "spacing": {
    "0": { "value": "0" },
    "1": { "value": "4px" },
    "2": { "value": "8px" },
    "3": { "value": "12px" },
    "4": { "value": "16px" },
    "5": { "value": "20px" },
    "6": { "value": "24px" },
    "8": { "value": "32px" },
    "10": { "value": "40px" },
    "12": { "value": "48px" }
  }
}

Additional Token Types

Shadow tokens define elevation and depth:

{
  "shadow": {
    "sm": { "value": "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
    "md": { "value": "0 4px 6px -1px rgba(0, 0, 0, 0.1)" },
    "lg": { "value": "0 10px 15px -3px rgba(0, 0, 0, 0.1)" }
  }
}

Border tokens define widths, styles, and radius:

{
  "border": {
    "width": {
      "thin": { "value": "1px" },
      "medium": { "value": "2px" },
      "thick": { "value": "4px" }
    },
    "radius": {
      "sm": { "value": "4px" },
      "md": { "value": "8px" },
      "lg": { "value": "16px" },
      "full": { "value": "9999px" }
    }
  }
}

Duration tokens define animation and transition timing:

{
  "duration": {
    "instant": { "value": "100ms" },
    "fast": { "value": "200ms" },
    "base": { "value": "300ms" },
    "slow": { "value": "500ms" }
  }
}

Token Formats

Design tokens can be stored in multiple formats. Each has trade-offs for readability, tooling support, and ecosystem compatibility.

JSON is the industry standard for design tokens. It's supported by all major tools, has excellent IDE support, and aligns with the W3C Design Tokens Format specification.

Advantages:

  • Universal support across tools (Style Dictionary, Token Studio, Figma Tokens)
  • Structured and machine-readable
  • Aligns with W3C specification (future-proof)
  • Easy to parse and validate

Disadvantages:

  • No comments (use JSONC or separate documentation)
  • More verbose than YAML

For the complete guide to structuring token JSON files, read our design tokens JSON guide, which covers the W3C specification, nested object structures, and token aliasing patterns.

YAML

YAML offers better readability with less syntax noise:

color:
  brand:
    primary:
      value: '#3B82F6'
  text:
    primary:
      value: '#0F172A'

Advantages:

  • Cleaner syntax with less punctuation
  • Native comment support
  • Better for human editing

Disadvantages:

  • Fewer tool integrations than JSON
  • Whitespace-sensitive (indentation errors break parsing)

JavaScript Objects

JavaScript objects enable programmatic token generation:

export const tokens = {
  color: {
    brand: {
      primary: { value: '#3B82F6' },
    },
  },
};

Advantages:

  • Native to JavaScript/TypeScript projects
  • Enables computed values and functions
  • Type-safe with TypeScript

Disadvantages:

  • Platform-specific (not usable for iOS/Android)
  • Requires build step for non-JS platforms

CSS Variables (Runtime Format)

CSS variables are not a token source format, but rather a consumption format for web applications:

:root {
  --color-brand-primary: #3B82F6;
  --color-text-primary: #0F172A;
  --spacing-md: 16px;
}

CSS variables enable runtime theming without JavaScript. Your token build process generates CSS variables from JSON source files. For the complete implementation guide, read our CSS variables design tokens guide.

Format Comparison

Format Readability Tool Support Platform Support Comments
JSON Good Excellent All platforms No (use JSONC)
YAML Excellent Good All platforms Yes
JavaScript Good Good JS/TS only Yes
CSS Variables Good Excellent Web only Yes

Recommendation: Use JSON as your source format, then transform to platform-specific formats (CSS variables for web, Swift for iOS, XML for Android) using Style Dictionary.

Token Tools

Several tools help you manage, transform, and consume design tokens. Here are the industry standards.

Style Dictionary (Industry Standard)

Style Dictionary is an open-source token build system created by Amazon. It's the de facto standard for transforming JSON tokens into platform-specific outputs.

Style Dictionary takes JSON token files and generates:

  • CSS variables for web
  • Sass variables for legacy projects
  • Swift constants for iOS
  • Kotlin/XML resources for Android
  • JSON for documentation

Here's a basic Style Dictionary configuration:

// style-dictionary.config.js
module.exports = {
  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: 'Tokens.swift',
        format: 'ios-swift/class.swift'
      }]
    }
  }
};

This configuration reads token JSON files from tokens/ and outputs CSS variables and Swift constants. Run style-dictionary build and both platforms update automatically.

For a complete walkthrough of Style Dictionary setup, transforms, and advanced patterns, read our Style Dictionary design tokens guide.

Figma Tokens Plugin

The Figma Tokens plugin enables designers to define and manage tokens directly in Figma. It syncs tokens between Figma and JSON files via GitHub, ensuring designers and developers work from the same source.

Key features:

  • Define tokens in Figma (colors, typography, spacing)
  • Export to JSON format compatible with Style Dictionary
  • Sync with GitHub for version control
  • Apply tokens to Figma design elements

Limitation: Requires manual token definition in Figma. For automated token extraction from existing designs, consider tools like HandoffPro.

Token Studio

Token Studio (formerly Figma Tokens Pro) is a newer alternative with enhanced features like token sets, themes, and multi-brand support.

HandoffPro (Automated Extraction)

HandoffPro automates token extraction from UI screenshots using vision AI. Instead of manually defining tokens in Figma or code, upload a screenshot and get a structured JSON token file instantly.

Use case: Rapidly prototype token systems from existing designs, extract tokens from legacy applications, or analyze competitor interfaces.

For developers working across design and code, HandoffPro eliminates the specification phase—you get structured tokens without manual extraction work. Learn more about design handoff automation.

Tool Comparison

Tool Best For Token Format Platform Output
Style Dictionary Build pipeline JSON → All platforms CSS, iOS, Android, etc.
Figma Tokens Designer-developer sync Figma ↔ JSON Requires Style Dictionary
Token Studio Multi-brand themes Figma ↔ JSON Requires Style Dictionary
HandoffPro Automated extraction Screenshot → JSON JSON source + CSS output

Workflow: Use Figma Tokens or HandoffPro to define/extract tokens → Use Style Dictionary to transform to platform-specific code.

Implementing Design Tokens

Once you have token files, you need to consume them in your applications. Implementation patterns vary by platform and framework.

In React Applications

React applications typically consume tokens via CSS variables. The token build process (Style Dictionary) generates CSS custom properties, which React components reference via className or CSS modules.

Basic pattern:

/* tokens.css - generated by Style Dictionary */
:root {
  --color-brand-primary: #3B82F6;
  --spacing-md: 16px;
  --font-size-lg: 18px;
}
// Button.jsx
export function Button({ children }) {
  return (
    <button style={{
      backgroundColor: 'var(--color-brand-primary)',
      padding: 'var(--spacing-md)',
      fontSize: 'var(--font-size-lg)'
    }}>
      {children}
    </button>
  );
}

Advanced pattern: Use a Theme Provider with React Context to enable runtime theme switching. For the complete React implementation guide including Theme Providers, CSS-in-JS integration, and TypeScript token types, read our design tokens React guide.

With Tailwind CSS

Tailwind projects inject tokens into the tailwind.config.js theme configuration:

// tailwind.config.js
const tokens = require('./tokens.json');
 
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          primary: tokens.color.brand.primary.value,
          secondary: tokens.color.brand.secondary.value,
        },
      },
      spacing: {
        xs: tokens.spacing.xs.value,
        sm: tokens.spacing.sm.value,
        md: tokens.spacing.md.value,
      },
    },
  },
};

Now Tailwind utility classes reference your token values:

<button className="bg-brand-primary px-md py-sm">
  Click Me
</button>

For the complete Tailwind integration guide including automated config generation, CSS variable alternatives, and JIT mode optimization, read our design tokens Tailwind guide.

In Plain CSS

For projects without frameworks, consume tokens as CSS custom properties:

/* Load generated token variables */
@import './tokens.css';
 
/* Use tokens in component styles */
.card {
  background: var(--color-bg-primary);
  border: var(--border-width-thin) solid var(--color-border-base);
  border-radius: var(--border-radius-md);
  padding: var(--spacing-md);
  box-shadow: var(--shadow-md);
}

Token Architecture: Primitive vs Semantic vs Component

The most maintainable token systems use a three-tier architecture: primitive tokens define raw values, semantic tokens assign contextual meaning, and component tokens provide component-specific overrides.

Tier 1: Primitive Tokens

Primitive tokens are absolute values without context. They define your color palette, spacing scale, and typography scale:

{
  "color": {
    "blue": {
      "500": { "value": "#3B82F6" },
      "900": { "value": "#1E3A8A" }
    }
  },
  "spacing": {
    "4": { "value": "16px" },
    "6": { "value": "24px" }
  }
}

Use primitive tokens to: Define your design foundation without any semantic meaning.

Never reference primitives directly in components. Components should use semantic or component tokens that alias primitives.

Tier 2: Semantic Tokens

Semantic tokens assign contextual meaning to primitive tokens:

{
  "color": {
    "brand": {
      "primary": { "value": "{color.blue.500}" }
    },
    "text": {
      "primary": { "value": "{color.gray.900}" }
    }
  },
  "spacing": {
    "section": { "value": "{spacing.6}" }
  }
}

Notice the {color.blue.500} syntax—this is token aliasing, where semantic tokens reference primitive tokens.

Use semantic tokens to: Assign meaning and enable theme switching. Changing color.brand.primary from {color.blue.500} to {color.red.500} rebrand your entire application.

Tier 3: Component Tokens

Component tokens provide component-specific overrides:

{
  "component": {
    "button": {
      "bg": { "value": "{color.brand.primary}" },
      "text": { "value": "#FFFFFF" },
      "padding": { "value": "{spacing.4}" }
    },
    "card": {
      "bg": { "value": "{color.bg.secondary}" },
      "border": { "value": "{color.border.base}" }
    }
  }
}

Component tokens enable per-component customization without polluting your semantic token namespace.

Why Three Tiers Matter

This architecture provides flexibility and maintainability:

  1. Rebrand from primitives: Change color.blue.500 to update all references
  2. Theme from semantics: Change color.brand.primary to switch themes without touching primitives
  3. Override at component level: Change button.bg to customize button appearance without affecting other components

Here's how it looks in generated CSS:

/* Primitive tokens (tier 1) */
:root {
  --color-blue-500: #3B82F6;
  --spacing-4: 16px;
}
 
/* Semantic tokens (tier 2) */
:root {
  --color-brand-primary: var(--color-blue-500);
  --spacing-section: var(--spacing-4);
}
 
/* Component tokens (tier 3) */
:root {
  --button-bg: var(--color-brand-primary);
  --button-padding: var(--spacing-4);
}

Components reference tier 3 tokens, which reference tier 2, which reference tier 1. Change any tier and the cascade updates automatically.

Multi-Platform Token Strategy

The ultimate power of design tokens emerges in multi-platform environments. Companies like Salesforce, Shopify, and GitHub maintain consistent design systems across web, iOS, and Android from a single token source.

One Source, Multiple Outputs

A multi-platform token workflow looks like this:

  1. Single source: Define tokens in JSON
  2. Transform: Use Style Dictionary to generate platform-specific code
  3. Consume: Each platform uses its native format (CSS variables, Swift constants, XML resources)

Example Style Dictionary configuration for all three platforms:

module.exports = {
  source: ['tokens/**/*.json'],
  platforms: {
    css: {
      transformGroup: 'css',
      buildPath: 'build/web/',
      files: [{
        destination: 'tokens.css',
        format: 'css/variables'
      }]
    },
    ios: {
      transformGroup: 'ios-swift',
      buildPath: 'build/ios/',
      files: [{
        destination: 'Tokens.swift',
        format: 'ios-swift/class.swift'
      }]
    },
    android: {
      transformGroup: 'android',
      buildPath: 'build/android/',
      files: [{
        destination: 'tokens.xml',
        format: 'android/resources'
      }]
    }
  }
};

This single configuration outputs:

Web (CSS variables):

:root {
  --color-brand-primary: #3B82F6;
  --spacing-md: 16px;
}

iOS (Swift constants):

public class Tokens {
  public static let colorBrandPrimary = UIColor(hex: 0x3B82F6)
  public static let spacingMd: CGFloat = 16
}

Android (XML resources):

<resources>
  <color name="color_brand_primary">#3B82F6</color>
  <dimen name="spacing_md">16dp</dimen>
</resources>

Platform-Specific Considerations

Each platform has unique requirements:

iOS: Colors need UIColor objects, spacing needs CGFloat units Android: Colors use hex format, spacing uses dp (density-independent pixels) Web: Colors can be hex/rgb/hsl, spacing typically uses px or rem

Style Dictionary handles these transformations automatically via transform groups. Your token source remains platform-agnostic—the build process adapts to each platform's conventions.

For the complete multi-platform guide including Figma integration, token synchronization workflows, and platform-specific transforms, read our multi-platform design tokens guide.

Design Tokens and Design Handoff

Design tokens fundamentally change the design handoff process. Instead of developers manually extracting specifications from Figma—measuring spacing, copying hex codes, guessing font weights—tokens provide machine-readable specifications that eliminate the entire specification phase.

Traditional Handoff (Without Tokens)

  1. Designer creates mockup in Figma
  2. Developer opens Figma inspect panel
  3. Developer manually extracts each value (colors, spacing, typography)
  4. Developer translates values to code
  5. Developer asks clarifying questions about missing specs
  6. Designer provides additional details
  7. Repeat steps 3-6 for each component

Time: 4-8 hours for a complex screen. Error rate: High—developers miss hover states, responsive breakpoints, and edge cases.

Token-Based Handoff

  1. Designer defines tokens in Figma Tokens plugin (or tokens auto-extracted via HandoffPro)
  2. Tokens sync to GitHub as JSON
  3. Style Dictionary builds platform-specific code
  4. Developer imports token CSS/Swift/XML
  5. Developer references tokens in components

Time: 30-60 minutes for the same screen. Error rate: Near zero—tokens are version-controlled and validated.

For teams serious about eliminating handoff friction, tokens are non-negotiable. Learn more about design handoff automation and how modern workflows integrate tokens from the start.

HandoffPro: Token Extraction from Screenshots

HandoffPro automates token extraction from UI screenshots using vision AI. Upload a design screenshot and get a structured JSON token file covering:

  • Complete color palette with semantic naming
  • Typography specifications (family, size, weight, line-height)
  • Spacing system based on detected padding/margin values
  • Component breakdown with token references

This eliminates the manual token definition phase—you get production-ready tokens from existing designs in seconds, not hours.

FAQ

Q: What are design tokens?

A: Design tokens are design decisions stored as data. They represent values like colors, spacing, typography, and animations in a platform-agnostic format (typically JSON or YAML) that can be transformed into platform-specific code like CSS variables, iOS Swift constants, or Android XML resources. Tokens provide a single source of truth for design systems.

Q: Why should developers use design tokens?

A: Design tokens eliminate hard-coded values throughout your codebase, enabling theme changes to propagate instantly across all platforms from a single update. They prevent design drift between platforms, reduce maintenance time by 40-60%, and enable automated design handoff workflows that eliminate manual specification extraction from design tools.

Q: What is the W3C Design Tokens Format?

A: The W3C Design Tokens Format is a community specification that standardizes how design tokens are structured in JSON. It defines syntax for token types (color, dimension, duration), value formats, and metadata. Using this format ensures your tokens are portable across tools and platforms, preventing vendor lock-in to proprietary token formats.

Q: How do I implement design tokens in React?

A: The most common React implementation uses CSS variables as the runtime format, with tokens defined in :root and consumed via className or CSS modules. Advanced patterns include Theme Providers with React Context, CSS-in-JS token consumption, or utility classes generated from tokens. The key is separating token definitions (JSON) from consumption (React components).

Q: What tools should I use to manage design tokens?

A: Style Dictionary (Amazon) is the industry standard for transforming JSON tokens into platform-specific outputs. For design tool integration, use Figma Tokens plugin or Token Studio to extract tokens from Figma designs. HandoffPro automates token extraction from screenshots, generating structured JSON tokens without manual specification work.

Start Using Design Tokens

Design tokens transform how you build and maintain design systems. Instead of searching hundreds of files to update a single color, you change one JSON value and all platforms update automatically.

Recommended workflow for new projects:

  1. Define tokens in JSON using the W3C format structure
  2. Set up Style Dictionary to generate platform-specific code
  3. Consume tokens via CSS variables (web), Swift (iOS), or XML (Android)
  4. Version control your token JSON alongside code
  5. Automate token builds in your CI/CD pipeline

For existing projects with established designs:

  1. Use HandoffPro to extract tokens from design screenshots
  2. Review and refine the generated token structure
  3. Integrate Style Dictionary to transform tokens for your platforms
  4. Gradually migrate components from hard-coded values to token references
  5. Document token usage patterns for your team

Design tokens are not just a convenience—they're the foundation of scalable, maintainable design systems. Start with a single component, prove the value, then expand token usage across your codebase.

Ready to automate token extraction from your designs? Try HandoffPro to generate structured token JSON from screenshots in seconds.

Stop Extracting Design Values Manually

Upload a Figma screenshot and get JSONC tokens + a Claude-ready prompt in 30 seconds.

Cookie Preferences

We use cookies for analytics and advertising. Essential cookies are always enabled. Learn more

Design Tokens: The Complete Guide for Developers | HandoffPro