style-dictionary
Skill50 starsChanged 11 months agoMITView on GitHub
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.
- Deletes or force-pushes
- Installs packages
In this repository29 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- aria-patternsSkill
- color-contrastSkill
- focus-statesSkill
- component-docsSkill
- token-docsSkill
- angularSkill
- reactSkill
- svelteSkill
- vueSkill
- getting-startedSkill
- animation-principlesSkill
- compound-componentsSkill
- dark-modeSkill
- icon-systemSkill
- layout-primitivesSkill
- breakpointsSkill
- color-scaleSkill
- design-tokens-structureSkill
- motion-scaleSkill
- radius-scaleSkill
- responsive-typographySkill
- shadow-scaleSkill
- spacing-scaleSkill
- type-scaleSkill
- z-index-scaleSkill
- figmaSkill
- framerSkill
- storybookSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 33
Set up config: Create style-dictionary.config.js
- Distinctive: line 34
Define transforms: Add any custom value transformations
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
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 correctlyProject Setup
Installation
npm install style-dictionary
# or
yarn add style-dictionaryDirectory 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.jsConfiguration
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 brandTheme-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 buildGitHub 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 buildDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

