Agent skill
style-dictionary
Transforms design tokens into platform-specific formats (CSS, SCSS, iOS Swift, Android XML). Use when setting up multi-platform token pipelines, creating build processes, or managing cross-platform design systems.
Install this agent skill to your Project
npx add-skill https://github.com/dylantarre/design-system-skills/tree/main/skills/tools/style-dictionary
SKILL.md
Style Dictionary
Overview
Set up Style Dictionary to transform design tokens into platform-specific formats. The industry standard for design systems that need to output to web, iOS, Android, and other platforms from a single token source.
When to Use
- Setting up a new design system with multi-platform needs
- Converting Figma tokens to code
- Generating CSS, SCSS, iOS Swift, Android XML from one source
- Adding custom token transforms or formats
- Integrating tokens into a build pipeline
Quick Reference: Core Concepts
| Concept | Purpose | Example |
|---|---|---|
| Token | Design value with metadata | { "value": "#3b82f6", "type": "color" } |
| Transform | Converts token values | color/hex → color/rgb |
| Format | Outputs to file type | CSS variables, Swift, XML |
| Platform | Target environment | web, ios, android |
The Process
- Assess token sources: Where are tokens defined? (Figma, JSON, YAML)
- Identify platforms: Which platforms need tokens?
- Set up config: Create
style-dictionary.config.js - Define transforms: Add any custom value transformations
- Build: Run
style-dictionary build
Implementation Checklist
Copy this checklist when setting up Style Dictionary:
Style Dictionary Setup:
- [ ] Install: `npm install style-dictionary`
- [ ] Create tokens/ directory with source JSON files
- [ ] Create style-dictionary.config.js with source paths and platform outputs
- [ ] Add build script to package.json: `"tokens:build": "style-dictionary build"`
- [ ] Run build and verify output files are generated correctly
Project Setup
Installation
npm install style-dictionary
# or
yarn add style-dictionary
Directory Structure
tokens/
├── base/
│ ├── colors.json
│ ├── spacing.json
│ └── typography.json
├── semantic/
│ ├── colors.json
│ └── components.json
└── themes/
├── light.json
└── dark.json
build/ # Generated output
├── css/
│ └── variables.css
├── ios/
│ └── StyleDictionary.swift
└── android/
└── colors.xml
style-dictionary.config.js
Configuration
Basic Config
// style-dictionary.config.js
module.exports = {
source: ['tokens/**/*.json'],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'build/css/',
files: [
{
destination: 'variables.css',
format: 'css/variables',
},
],
},
},
};
Multi-Platform Config
// style-dictionary.config.js
module.exports = {
source: ['tokens/**/*.json'],
platforms: {
// Web - CSS Custom Properties
css: {
transformGroup: 'css',
buildPath: 'build/css/',
files: [
{
destination: 'variables.css',
format: 'css/variables',
options: {
outputReferences: true, // Keep token references
},
},
],
},
// Web - SCSS Variables
scss: {
transformGroup: 'scss',
buildPath: 'build/scss/',
files: [
{
destination: '_variables.scss',
format: 'scss/variables',
},
],
},
// Web - JavaScript/TypeScript
js: {
transformGroup: 'js',
buildPath: 'build/js/',
files: [
{
destination: 'tokens.js',
format: 'javascript/es6',
},
{
destination: 'tokens.d.ts',
format: 'typescript/es6-declarations',
},
],
},
// iOS - Swift
ios: {
transformGroup: 'ios-swift',
buildPath: 'build/ios/',
files: [
{
destination: 'StyleDictionary.swift',
format: 'ios-swift/class.swift',
className: 'StyleDictionary',
},
],
},
// Android - XML Resources
android: {
transformGroup: 'android',
buildPath: 'build/android/',
files: [
{
destination: 'colors.xml',
format: 'android/colors',
filter: { type: 'color' },
},
{
destination: 'dimens.xml',
format: 'android/dimens',
filter: { type: 'dimension' },
},
],
},
},
};
Token Format
Design Tokens Community Group (DTCG) Format
{
"color": {
"primary": {
"$value": "#3b82f6",
"$type": "color",
"$description": "Primary brand color"
},
"secondary": {
"$value": "#64748b",
"$type": "color"
}
},
"spacing": {
"sm": {
"$value": "8px",
"$type": "dimension"
},
"md": {
"$value": "16px",
"$type": "dimension"
}
}
}
Style Dictionary Classic Format
{
"color": {
"primary": {
"value": "#3b82f6",
"type": "color",
"comment": "Primary brand color"
}
},
"spacing": {
"sm": { "value": "8px" },
"md": { "value": "16px" }
}
}
Token References (Aliases)
{
"color": {
"base": {
"blue": {
"500": { "value": "#3b82f6" }
}
},
"primary": {
"value": "{color.base.blue.500}"
},
"button": {
"background": {
"value": "{color.primary}"
}
}
}
}
Custom Transforms
Register Custom Transform
// style-dictionary.config.js
const StyleDictionary = require('style-dictionary');
// Transform px to rem
StyleDictionary.registerTransform({
name: 'size/pxToRem',
type: 'value',
matcher: (token) => token.type === 'dimension',
transformer: (token) => {
const px = parseFloat(token.value);
return `${px / 16}rem`;
},
});
// Transform color to OKLCH
StyleDictionary.registerTransform({
name: 'color/oklch',
type: 'value',
matcher: (token) => token.type === 'color',
transformer: (token) => {
// Use a color library like culori
const { formatCss, oklch, parse } = require('culori');
return formatCss(oklch(parse(token.value)));
},
});
module.exports = {
source: ['tokens/**/*.json'],
platforms: {
css: {
transforms: [
'attribute/cti',
'name/cti/kebab',
'size/pxToRem', // Custom
'color/oklch', // Custom
],
buildPath: 'build/css/',
files: [
{
destination: 'variables.css',
format: 'css/variables',
},
],
},
},
};
Common Custom Transforms
// Clamp font sizes for fluid typography
StyleDictionary.registerTransform({
name: 'size/fluidType',
type: 'value',
matcher: (token) => token.attributes?.category === 'font' && token.attributes?.type === 'size',
transformer: (token) => {
const min = parseFloat(token.value) * 0.875;
const max = parseFloat(token.value);
return `clamp(${min}rem, 2vw + 1rem, ${max}rem)`;
},
});
// Shadow to CSS format
StyleDictionary.registerTransform({
name: 'shadow/css',
type: 'value',
matcher: (token) => token.type === 'shadow',
transformer: (token) => {
const { x, y, blur, spread, color } = token.value;
return `${x}px ${y}px ${blur}px ${spread}px ${color}`;
},
});
Custom Formats
CSS with Dark Mode
StyleDictionary.registerFormat({
name: 'css/variables-themed',
formatter: ({ dictionary, options }) => {
const lightTokens = dictionary.allTokens
.filter(t => !t.path.includes('dark'))
.map(t => ` --${t.name}: ${t.value};`)
.join('\n');
const darkTokens = dictionary.allTokens
.filter(t => t.path.includes('dark'))
.map(t => {
const name = t.name.replace('dark-', '');
return ` --${name}: ${t.value};`;
})
.join('\n');
return `:root {\n${lightTokens}\n}\n\n[data-theme="dark"] {\n${darkTokens}\n}`;
},
});
Tailwind Config Format
StyleDictionary.registerFormat({
name: 'tailwind/config',
formatter: ({ dictionary }) => {
const colors = {};
const spacing = {};
dictionary.allTokens.forEach(token => {
if (token.type === 'color') {
const path = token.path.slice(1).join('-');
colors[path] = token.value;
}
if (token.type === 'dimension' && token.path[0] === 'spacing') {
spacing[token.path[1]] = token.value;
}
});
return `module.exports = {
theme: {
extend: {
colors: ${JSON.stringify(colors, null, 2)},
spacing: ${JSON.stringify(spacing, null, 2)},
},
},
};`;
},
});
Multi-Theme Setup
Token Structure
tokens/
├── core/
│ ├── colors.json # Primitives (blue-500, gray-100)
│ └── spacing.json
├── semantic/
│ ├── light.json # Semantic mappings for light
│ └── dark.json # Semantic mappings for dark
└── brand/
├── default.json # Default brand
└── partner.json # White-label brand
Theme-Specific Config
// style-dictionary.config.js
const themes = ['light', 'dark'];
const brands = ['default', 'partner'];
module.exports = {
source: ['tokens/core/**/*.json'],
platforms: brands.flatMap(brand =>
themes.map(theme => ({
[`css-${brand}-${theme}`]: {
transformGroup: 'css',
buildPath: `build/${brand}/`,
files: [
{
destination: `${theme}.css`,
format: 'css/variables',
filter: (token) =>
token.filePath.includes('core') ||
token.filePath.includes(theme),
},
],
source: [
`tokens/semantic/${theme}.json`,
`tokens/brand/${brand}.json`,
],
},
}))
),
};
Build Pipeline Integration
package.json Scripts
{
"scripts": {
"tokens:build": "style-dictionary build",
"tokens:watch": "style-dictionary build --watch",
"tokens:clean": "rm -rf build/",
"prebuild": "npm run tokens:build"
}
}
With Figma Tokens Plugin
# 1. Export from Figma Tokens plugin to tokens/figma.json
# 2. Transform with Style Dictionary
npx token-transformer tokens/figma.json tokens/transformed.json
style-dictionary build
GitHub Action
# .github/workflows/tokens.yml
name: Build Tokens
on:
push:
paths:
- 'tokens/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm run tokens:build
- uses: actions/upload-artifact@v4
with:
name: tokens
path: build/
Output Examples
Input Token
{
"color": {
"primary": {
"value": "#3b82f6",
"type": "color"
}
}
}
CSS Output
:root {
--color-primary: #3b82f6;
}
SCSS Output
$color-primary: #3b82f6;
JavaScript Output
export const ColorPrimary = '#3b82f6';
iOS Swift Output
public class StyleDictionary {
public static let colorPrimary = UIColor(red: 0.231, green: 0.510, blue: 0.965, alpha: 1.0)
}
Android XML Output
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<color name="color_primary">#3b82f6</color>
</resources>
Common Issues & Solutions
| Issue | Solution |
|---|---|
| Circular references | Check token aliases don't loop |
| Token not found | Verify path in reference matches exactly |
| Wrong output format | Check transform group matches platform |
| Missing tokens | Check filter isn't excluding them |
| Stale builds | Run tokens:clean before build |
Style Dictionary v4 (Latest)
// style-dictionary.config.js (v4 syntax)
import StyleDictionary from 'style-dictionary';
export default {
source: ['tokens/**/*.json'],
preprocessors: ['tokens-studio'], // For Figma Tokens
platforms: {
css: {
transformGroup: 'css',
buildPath: 'build/',
files: [{
destination: 'variables.css',
format: 'css/variables',
}],
},
},
};
# Run with ESM
node --experimental-json-modules ./node_modules/.bin/style-dictionary build
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
getting-started
Introduction to the design system skills plugin. Use when first installing the plugin, exploring available skills, or planning a design system implementation.
responsive-typography
Implements fluid typography using CSS clamp() that scales with viewport. Use when creating responsive font sizes, viewport-aware headings, or type that adapts smoothly without breakpoints.
spacing-scale
Generates consistent spacing tokens using base values and ratios. Use when creating margin/padding systems, gap tokens, or layout spacing. Outputs CSS custom properties, Tailwind config, or JSON tokens.
color-scale
Generates perceptually uniform OKLCH color palettes from brand colors. Use when creating color systems, theme palettes, or converting hex values to 11-step scales. Outputs CSS custom properties, Tailwind config, or JSON tokens.
shadow-scale
Generates layered box-shadow elevation tokens for depth hierarchy. Use when creating elevation systems, card shadows, modal depth, or dark mode shadow variants. Outputs CSS, Tailwind, or JSON.
breakpoints
Generates responsive breakpoint tokens for media queries and container queries. Use when setting up responsive design, mobile-first layouts, or viewport-based styling. Outputs CSS, Tailwind, or JSON.
Didn't find tool you were looking for?