Tutorial: Getting Started with CI/CD for Design Systems.
Skill Level: Intermediate (comfortable with Git, Node.js, design tokens)
Time Investment: 1–2 hours to set up a working pipeline
Prerequisites
Before starting, make sure you have:
GitHub (or GitLab/Bitbucket) repo to store your design tokens and components
Node.js installed (LTS recommended)
A CI/CD platform like GitHub Actions (free), CircleCI, or Buildkite
A package registry (npm, GitHub Packages, or private registry) for distribution
Optional but recommended:
Figma Tokens plugin or Specify.app → to sync tokens from design tools
Style Dictionary → to transform tokens for different platforms
Set Up Repo Structure
Here’s a simple structure for a design system repo:
design-system/
├── tokens/
│ ├── color.json
│ ├── spacing.json
│ └── typography.json
├── components/
│ ├── Button.jsx
│ └── Card.jsx
├── scripts/
│ └── build-tokens.js
├── package.json
└── .github/
└── workflows/
└── ci.yml
tokens/: JSON files defining tokens (color, spacing, typography).components/: React (or SwiftUI/Flutter) components powered by tokens.scripts/: Custom build scripts for transforming tokens..github/workflows/: GitHub Actions pipeline config.
Define Tokens
{
"color": {
"primary": { "value": "#004165" },
"secondary": { "value": "#007dba" },
"background": { "value": "#ffffff" }
}
}
Transform Tokens with Style Dictionary
Install Style Dictionary:
npm install style-dictionary --save-dev
Add build script scripts/build-tokens.js:
const StyleDictionary = require('style-dictionary');
StyleDictionary.extend({
source: ["tokens/**/*.json"],
platforms: {
css: {
transformGroup: "css",
buildPath: "build/css/",
files: [{ destination: "tokens.css", format: "css/variables" }]
},
js: {
transformGroup: "js",
buildPath: "build/js/",
files: [{ destination: "tokens.js", format: "javascript/es6" }]
}
}
}).buildAllPlatforms();
Now you can run:
node scripts/build-tokens.js
This outputs:
build/css/tokens.css- usable in web projectsbuild/js/tokens.js- usable in React components
Automate Component Builds
Example Button.jsx using tokens:
import tokens from '../build/js/tokens';
export default function Button({ label }) {
return (
<button
style={{
backgroundColor: tokens.color.primary.value,
color: tokens.color.background.value,
padding: "12px 20px",
borderRadius: "6px",
border: "none",
cursor: "pointer"
}}
>
{label}
</button>
);
}
Add CI/CD Pipeline
Here’s a GitHub Actions workflow (.github/workflows/ci.yml):
name: Design System CI/CD
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Dependencies
run: npm install
- name: Build Tokens
run: node scripts/build-tokens.js
- name: Run Tests
run: npm test
- name: Publish to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
This pipeline will:
Trigger on every push to main.
Run token build and tests.
Publish a new version of your design system package to npm.
Add Automated Documentation
Use Storybook (personal preference) or Docusaurus to generate live docs (others @ Jam Stack).
For example, Storybook can auto-render Button.jsx with tokens applied.
Add a CI step:
- name: Deploy Storybook run: npm run build-storybook && npx gh-pages -d storybook-static
Who’s Doing it Well
Shopify Polaris - Uses automated pipelines for updating design tokens across platforms.
IBM Carbon Design System - Runs CI/CD pipelines for React + Web Components + Sass tokens.
Adobe Spectrum - Uses automation to sync tokens from design tools into web frameworks.
Risks & Guardrails
Token sprawl - Enforce naming conventions and reviews.
Version control noise - Group related token changes.
Designer onboarding - Document the pipeline in Notion/Confluence etc.