Skip to content

W3C Design Tokens Format

When to Use

Use this when you need a vendor-neutral interchange format for sharing tokens across tools (Figma, Style Dictionary, Tailwind, native apps). The DTCG specification reached its first stable version (2025.10) in October 2025.

Composite Types

The spec supports complex design properties (shadows, typography, borders) that combine multiple sub-values. Shadow example:

{
  "shadow": {
    "card": {
      "$value": { "offsetX": "0px", "offsetY": "2px", "blur": "8px",
                  "spread": "0px", "color": "{color.neutral}" },
      "$type": "shadow"
    }
  }
}

Decision

Token Type $type Value Example $value
Color color "oklch(55% 0.3 240)"
Dimension dimension "0.5rem"
Font family fontFamily ["Inter", "system-ui", "sans-serif"]
Font weight fontWeight "600"
Duration duration "200ms"
Cubic bezier cubicBezier [0.4, 0, 0.2, 1]
Shadow shadow { offsetX, offsetY, blur, spread, color }
Border border { color, width, style }
Typography typography { fontFamily, fontSize, lineHeight, ... }

Pattern

Token File Structure

Files use .tokens.json extension and application/design-tokens+json media type.

{
  "color": {
    "primary": {
      "$value": "oklch(55% 0.3 240)",
      "$type": "color",
      "$description": "Main brand action color"
    },
    "primary-content": {
      "$value": "oklch(98% 0.01 240)",
      "$type": "color"
    }
  },
  "spacing": {
    "sm": { "$value": "0.5rem", "$type": "dimension" },
    "md": { "$value": "1rem", "$type": "dimension" },
    "lg": { "$value": "1.5rem", "$type": "dimension" }
  },
  "font-family": {
    "sans": {
      "$value": ["Inter", "system-ui", "sans-serif"],
      "$type": "fontFamily"
    }
  },
  "border-radius": {
    "field": { "$value": "0.5rem", "$type": "dimension" },
    "box": { "$value": "1rem", "$type": "dimension" }
  }
}

Token Aliases

Tokens reference other tokens with curly braces: "$value": "{color.blue-500}". This creates a dependency chain resolved at build time by tools like Style Dictionary.

Composite Types

Shadow example:

{
  "shadow": {
    "card": {
      "$value": { "offsetX": "0px", "offsetY": "2px", "blur": "8px",
                  "spread": "0px", "color": "{color.neutral}" },
      "$type": "shadow"
    }
  }
}

Conversion to Tailwind v4

Use Style Dictionary or a simple script to flatten DTCG JSON into @theme variables:

// dtcg-to-tailwind.mjs
import { readFileSync } from 'fs';
const tokens = JSON.parse(readFileSync('tokens.tokens.json', 'utf8'));

function toThemeVars(obj, prefix = '') {
  let vars = [];
  for (const [key, val] of Object.entries(obj)) {
    const path = prefix ? `${prefix}-${key}` : key;
    if (val.$value !== undefined) vars.push(`  --${path}: ${val.$value};`);
    else vars.push(...toThemeVars(val, path));
  }
  return vars;
}
console.log(`@theme {\n${toThemeVars(tokens).join('\n')}\n}`);

Common Mistakes

  • Wrong: Using custom $type values not in the spec. Right: Stick to official types for tool compatibility.
  • Wrong: Circular alias references. Right: Maintain a directed acyclic graph of token dependencies.

See Also