agentleFS
dylantarredylantarre/design-system-skills/skills/tools/style-dictionary/SKILL.md

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

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
  1. Very specific:

    Set up config: Create style-dictionary.config.js

    line 33
  2. Distinctive:

    Define transforms: Add any custom value transformations

    line 34

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
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

ConceptPurposeExample
TokenDesign value with metadata{ "value": "#3b82f6", "type": "color" }
TransformConverts token valuescolor/hex → color/rgb
FormatOutputs to file typeCSS variables, Swift, XML
PlatformTarget environmentweb, ios, android

The Process

  1. Assess token sources: Where are tokens defined? (Figma, JSON, YAML)
  2. Identify platforms: Which platforms need tokens?
  3. Set up config: Create style-dictionary.config.js
  4. Define transforms: Add any custom value transformations
  5. 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

IssueSolution
Circular referencesCheck token aliases don't loop
Token not foundVerify path in reference matches exactly
Wrong output formatCheck transform group matches platform
Missing tokensCheck filter isn't excluding them
Stale buildsRun 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

Download now (ZIP)

Does 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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.