If you're managing design tokens in a production design system, you've likely faced the question: how should I structure my tokens? Should they be in JSON, YAML, JavaScript objects, or CSS custom properties? And what format should each token follow—just a value string, or something more structured?
The W3C Design Tokens Community Group has published a specification to answer this question. The W3C Design Tokens Format standardizes how design tokens are structured in JSON, ensuring tokens are portable across design tools (Figma, Sketch), build tools (Style Dictionary, Theo), and platforms (web, iOS, Android).
This guide walks you through the W3C Design Tokens JSON format with complete examples, token aliasing, and validation techniques for production use.
TLDR
JSON is the recommended format for design tokens because it's platform-agnostic, machine-readable, and standardized by the W3C Design Tokens Community Group. The W3C format requires three properties: $value (the token value), $type (token type like color or dimension), and optionally $description (human-readable explanation). Tokens support aliasing (referencing other tokens) and are organized into groups for maintainability.
Key takeaways:
- W3C Design Tokens Format standardizes token structure with $value, $type, and $description properties
- Token types include color, dimension, fontFamily, fontWeight, duration, cubicBezier, and more
- Token aliasing uses {group.token} syntax to reference other tokens, creating semantic layers
- JSON enables cross-platform token usage (web CSS variables, iOS Swift, Android XML) via tools like Style Dictionary
- Validate token files with JSON Schema to catch structural errors before build
Why JSON for Design Tokens?
JSON (JavaScript Object Notation) has become the de facto standard for design token storage for several reasons:
Platform-agnostic: JSON is supported by every programming language and platform. You can parse JSON in JavaScript, Swift, Kotlin, Python, and any other language used for UI development.
Machine-readable: Build tools like Style Dictionary, Theo, and Figma Tokens plugins consume JSON token files and transform them into platform-specific formats (CSS variables, iOS Swift constants, Android XML resources).
Human-readable: While less readable than YAML, JSON is still relatively easy for humans to read and edit. Adding comments requires JSONC (JSON with Comments) or JSON5 extensions.
W3C standardization: The W3C Design Tokens Community Group has chosen JSON as the official format for the specification, giving it legitimacy and long-term support.
Tooling ecosystem: Most design token tools (Style Dictionary, Figma Tokens, Theo, Amazon Style Dictionary) expect JSON input and provide JSON output.
JSON is the recommended format for design tokens because it balances machine readability, human editability, and cross-platform compatibility.
W3C Design Tokens Format
The W3C Design Tokens Format specification defines how tokens should be structured in JSON. The core structure requires three properties:
$value: The actual design value (e.g., "#3b82f6" for a color, "16px" for a dimension)
$type: The token type (e.g., "color", "dimension", "fontFamily") that determines how the value is interpreted and transformed
$description (optional): A human-readable description of the token's purpose
Valid W3C token example:
{
"color": {
"primary": {
"$value": "#3b82f6",
"$type": "color",
"$description": "Primary brand color used for buttons, links, and key UI elements"
}
}
}Key conventions:
- Property names starting with
$are reserved for specification-defined properties - Token values can be strings, numbers, or objects depending on the token type
- Tokens are organized into nested groups (e.g.,
color.brand.primary,spacing.sm) - Each token must have a
$value, but$typecan be inherited from parent groups
The W3C format ensures that any tool complying with the specification can correctly parse and transform your tokens.
Token Types
The W3C specification defines standard token types that cover most design system needs:
Color
Represents color values in hex, RGB, or named format.
{
"color": {
"primary": {
"$value": "#3b82f6",
"$type": "color"
},
"secondary": {
"$value": "rgb(139, 92, 246)",
"$type": "color"
}
}
}Dimension
Represents size, spacing, or length values with units (px, rem, em, %).
{
"spacing": {
"sm": {
"$value": "8px",
"$type": "dimension"
},
"md": {
"$value": "16px",
"$type": "dimension"
},
"lg": {
"$value": "1.5rem",
"$type": "dimension"
}
}
}Font Family
Represents font family names (with fallback stack).
{
"font": {
"family": {
"sans": {
"$value": "Inter, system-ui, -apple-system, sans-serif",
"$type": "fontFamily"
},
"mono": {
"$value": "Fira Code, Consolas, monospace",
"$type": "fontFamily"
}
}
}
}Font Weight
Represents font weight values (100-900 or named weights).
{
"font": {
"weight": {
"regular": {
"$value": 400,
"$type": "fontWeight"
},
"semibold": {
"$value": 600,
"$type": "fontWeight"
},
"bold": {
"$value": 700,
"$type": "fontWeight"
}
}
}
}Duration
Represents animation or transition duration.
{
"animation": {
"duration": {
"fast": {
"$value": "150ms",
"$type": "duration"
},
"normal": {
"$value": "300ms",
"$type": "duration"
}
}
}
}Cubic Bezier
Represents easing curves for animations.
{
"animation": {
"easing": {
"smooth": {
"$value": [0.4, 0.0, 0.2, 1],
"$type": "cubicBezier",
"$description": "Material Design standard easing"
}
}
}
}Additional Types
The specification also defines: strokeStyle, border, transition, shadow, gradient, typography, and number types for more complex design values.
Token Aliasing and References
One of the most powerful features of design tokens is aliasing—the ability to reference other tokens. This creates a two-tier system:
Primitive tokens: Raw design values (e.g., blue.500: "#3b82f6")
Semantic tokens: Context-specific names that reference primitives (e.g., color.primary: "{color.blue.500}")
Syntax: Use curly braces {group.token} to reference another token.
Example with aliasing:
{
"color": {
"blue": {
"400": {
"$value": "#60a5fa",
"$type": "color"
},
"500": {
"$value": "#3b82f6",
"$type": "color"
},
"600": {
"$value": "#2563eb",
"$type": "color"
}
},
"gray": {
"700": {
"$value": "#374151",
"$type": "color"
},
"900": {
"$value": "#111827",
"$type": "color"
}
},
"semantic": {
"primary": {
"$value": "{color.blue.500}",
"$type": "color",
"$description": "Primary brand color for buttons and links"
},
"primaryHover": {
"$value": "{color.blue.600}",
"$type": "color"
},
"textPrimary": {
"$value": "{color.gray.900}",
"$type": "color"
},
"textSecondary": {
"$value": "{color.gray.700}",
"$type": "color"
}
}
}
}Why aliasing matters:
- Semantic layer: Use meaningful names (
primary,textSecondary) instead of raw values (blue-500,gray-700) - Single source changes: Change
blue.500once, and all tokens referencing it update automatically - Theme switching: Swap semantic token references (light theme:
primary: "{blue.500}", dark theme:primary: "{blue.400}") without changing component code
Build tools like Style Dictionary resolve token references during transformation, outputting final values in platform-specific formats.
Code Example: Complete Token File
Here's a production-ready token file following the W3C format with primitives, semantic tokens, and aliasing:
{
"$schema": "https://design-tokens.org/schema.json",
"color": {
"$type": "color",
"blue": {
"400": { "$value": "#60a5fa" },
"500": { "$value": "#3b82f6" },
"600": { "$value": "#2563eb" }
},
"gray": {
"50": { "$value": "#f9fafb" },
"100": { "$value": "#f3f4f6" },
"700": { "$value": "#374151" },
"900": { "$value": "#111827" }
},
"semantic": {
"primary": {
"$value": "{color.blue.500}",
"$description": "Primary brand color"
},
"primaryHover": {
"$value": "{color.blue.600}",
"$description": "Primary hover state"
},
"background": {
"$value": "{color.gray.50}",
"$description": "Default page background"
},
"textPrimary": {
"$value": "{color.gray.900}",
"$description": "Primary text color"
},
"textSecondary": {
"$value": "{color.gray.700}",
"$description": "Secondary text color"
}
}
},
"spacing": {
"$type": "dimension",
"xs": { "$value": "4px" },
"sm": { "$value": "8px" },
"md": { "$value": "16px" },
"lg": { "$value": "24px" },
"xl": { "$value": "32px" },
"2xl": { "$value": "48px" }
},
"font": {
"family": {
"$type": "fontFamily",
"sans": {
"$value": "Inter, system-ui, -apple-system, sans-serif",
"$description": "Default sans-serif font stack"
},
"mono": {
"$value": "Fira Code, Consolas, monospace",
"$description": "Monospace font for code"
}
},
"size": {
"$type": "dimension",
"sm": { "$value": "14px" },
"base": { "$value": "16px" },
"lg": { "$value": "18px" },
"xl": { "$value": "24px" },
"2xl": { "$value": "32px" }
},
"weight": {
"$type": "fontWeight",
"regular": { "$value": 400 },
"medium": { "$value": 500 },
"semibold": { "$value": 600 },
"bold": { "$value": 700 }
}
},
"borderRadius": {
"$type": "dimension",
"sm": { "$value": "4px" },
"md": { "$value": "8px" },
"lg": { "$value": "12px" },
"full": { "$value": "9999px" }
}
}Note the $schema property at the top: This enables JSON Schema validation and IDE autocomplete for W3C-compliant tokens.
Note $type inheritance: The $type property is defined once at the group level (e.g., color.$type: "color") and inherited by all tokens in that group. This reduces repetition.
Exporting Tokens from Design Tools
Most design tools don't natively export tokens in W3C JSON format, but plugins bridge the gap.
Figma Tokens Plugin
Figma Tokens (formerly Figma Tokens Studio) is the most popular Figma plugin for design token management.
Workflow:
- Install Figma Tokens plugin in your Figma file
- Designer defines color styles, text styles, and effects as tokens in the plugin
- Export tokens as JSON in W3C format
- Developer imports JSON into Style Dictionary or build pipeline
- Tokens are transformed into CSS, iOS, Android, etc.
Exported format from Figma Tokens:
{
"color": {
"primary": {
"$value": "#3b82f6",
"$type": "color"
}
},
"spacing": {
"md": {
"$value": "16",
"$type": "dimension"
}
}
}The plugin follows the W3C format with minor variations (some versions omit units from dimension values).
Sketch Token Export
Sketch doesn't have official token export, but community plugins like Sketch Tokens provide similar functionality to Figma Tokens.
Validating Token Files
To catch errors before tokens reach production, use JSON Schema validation. The W3C Design Tokens Community Group provides an official JSON Schema for the format.
Step 1: Install a JSON Schema validator
npm install --save-dev ajv ajv-cliStep 2: Create a validation script
// validate-tokens.js
const Ajv = require('ajv');
const tokens = require('./tokens.json');
const schema = require('./design-tokens-schema.json'); // W3C schema
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(tokens);
if (!valid) {
console.error('Token validation failed:');
console.error(validate.errors);
process.exit(1);
}
console.log('Tokens are valid!');Step 3: Run validation in CI/CD
node validate-tokens.jsThis ensures invalid tokens (missing $value, wrong $type, broken references) are caught before deployment.
TypeScript types for tokens:
You can also generate TypeScript types from your token JSON for type-safe token access in code:
// tokens.d.ts (generated from tokens.json)
export interface DesignTokens {
color: {
primary: string;
secondary: string;
textPrimary: string;
};
spacing: {
sm: string;
md: string;
lg: string;
};
}Now you get autocomplete and type checking when accessing tokens in your codebase. You can transform JSON tokens into CSS variables for runtime theming or import them directly into JavaScript/TypeScript.
FAQ
Q: What is the W3C Design Tokens Format?
A: The W3C Design Tokens Format is a community specification published by the W3C Design Tokens Community Group that standardizes how design tokens are structured in JSON. It defines required properties ($value, $type, $description) and token types (color, dimension, fontFamily, fontWeight, duration, cubicBezier) to ensure tokens are portable across design tools and platforms.
Q: How does token aliasing work in JSON?
A: Token aliasing allows one token to reference another using curly brace syntax: {group.tokenName}. This creates a dependency chain where semantic tokens reference primitive tokens. For example, {color.primary} might reference {color.blue.500}, enabling you to change semantic meanings (primary color) without updating every use case.
Q: Should I use JSON or YAML for design tokens?
A: JSON is the recommended format for design tokens because it's the W3C standard format, has broader tooling support (Style Dictionary, Figma Tokens, Theo), is machine-readable by all platforms (web, iOS, Android), and can be validated with JSON Schema. YAML is more human-readable but requires conversion to JSON for most token tools.