Automating Design Token Changes as PRs with Tokens Studio + Style Dictionary + GitHub Actions
What if a designer changed a button color to #3B82F6 in Figma, but the developer's code still had #3B82F5? Manually copying and pasting color values, sending a "just updated the tokens" message on Slack, and having developers edit CSS files by hand only leads to more mistakes and delays as the team grows. There are alternatives — managing CSS Variables directly, or adopting SaaS solutions like Supernova or Specify. But if you're looking for an approach that integrates naturally with your existing GitHub workflow, can be built entirely with open-source tools, and has a PR review process baked in, the pipeline introduced in this article is the most practical choice.
This article walks you step by step through setting up an end-to-end pipeline where the Tokens Studio plugin automatically pushes Figma changes to GitHub, GitHub Actions uses Style Dictionary and sd-transforms to generate platform-specific code, and a Pull Request is created automatically. The Smallstep team reported cutting their UI development time in half after adopting this pipeline, and this architecture is already a proven standard across many organizations. We'll cover what each layer does, how to actually configure it, and the common pitfalls to avoid — all from a practical perspective.
Core Concepts
Drift: The phenomenon where two parts of a system (here, design and code) diverge from each other over time. The core purpose of this pipeline is to structurally prevent drift.
The Role of Each Layer
TL;DR: Tokens Studio pushes JSON to GitHub, Style Dictionary transforms it into platform-specific code, and GitHub Actions creates the PR.
This pipeline operates with three independent layers working in concert.
| Layer | Tool | Role |
|---|---|---|
| Token Management | Tokens Studio (Figma plugin) | Define and manage design tokens, bidirectional GitHub sync |
| Canvas Representation | Figma Variables | Represent Tokens Studio output in a form usable on the Figma canvas |
| Code Transformation | GitHub Actions + Style Dictionary | Convert JSON → platform-specific code and auto-generate PRs |
The entire flow can be summarized in one sequence:
Designer (edits tokens in Tokens Studio)
→ Tokens Studio pushes JSON to figma-tokens branch
→ GitHub Actions triggered
→ Style Dictionary + sd-transforms generate CSS variables, Tailwind config, etc.
→ peter-evans/create-pull-request automatically creates a PR to mainTokens Studio vs Figma Variables — Division of Roles, Not Competition
Many people ask, "If I use Tokens Studio, do I even need Figma Variables?" The short answer is that they are not competing — their roles are clearly distinct.
Core principle: Tokens Studio is the Single Source of Truth (SSOT) for the system, and Figma Variables is the output layer that represents that result in a form usable on the canvas. Changes must always originate in Tokens Studio.
Editing Figma Variables directly creates drift between Tokens Studio's JSON and the Figma canvas. There's also one important constraint to be aware of: of the 23 token types Tokens Studio supports, Figma Variables only supports 4 — Color, Number, String, and Boolean. Typography and effect tokens can only be handled via Figma Styles.
W3C DTCG Standards and Why sd-transforms Is Needed
TL;DR: Tokens Studio JSON and the W3C standard format are subtly different. sd-transforms bridges that gap.
One of the most significant changes between 2024 and 2025 is the adoption of the W3C Design Token Community Group (DTCG) standard. With the official release of Style Dictionary v4, the token JSON format using $value and $type keys is becoming the established standard.
// W3C DTCG standard format
{
"color": {
"brand": {
"primary": {
"$value": "#3B82F6",
"$type": "color",
"$description": "Primary brand color"
}
}
}
}In contrast, the JSON exported by Tokens Studio looks like this:
// Tokens Studio export format
{
"color": {
"brand": {
"primary": {
"value": "{color.palette.blue.500}",
"type": "color"
}
}
}
}There are two differences between the formats: value/type is used instead of $value/$type, and the value reference syntax ({color.palette.blue.500}) differs from Style Dictionary's default parsing rules. The registerTransforms() function from the @tokens-studio/sd-transforms package converts both of these differences into a format Style Dictionary can understand. Omitting this call will cause reference syntax to be output as literal strings, or the build will fail entirely.
Practical Implementation
Now that we understand the concepts, let's look at how to actually configure this. Follow along in three steps in order.
Step 1: Connecting a GitHub Branch in Tokens Studio
Open the Tokens Studio plugin in Figma and navigate to Settings → Token Storage → Add new credentials.
Provider: GitHub
Repository: your-org/design-system
Branch: figma-tokens ← The key is to use a dedicated branch, not main
File Path: tokens/
Token: ghp_xxxxxxxxxxxx ← GitHub Personal Access Token (repo scope)A GitHub Personal Access Token (PAT) can be generated at GitHub → Settings → Developer settings → Personal access tokens. Checking only the repo scope is sufficient. This may be unfamiliar to backend developers, but this token is the authentication credential that allows the Tokens Studio plugin to push files to your GitHub repository.
Setting the branch to a separate branch like figma-tokens here is the core design of this pipeline. When the plugin pushes JSON to this branch, GitHub Actions automatically creates a PR to main. Configuring it to push directly to main bypasses the review process.
| Setting | Recommended Value | Reason |
|---|---|---|
| Branch | figma-tokens |
Isolates Actions trigger and preserves the review process |
| File Path | tokens/ |
Must match the Style Dictionary source path |
| Token | PAT with repo scope | Push permission required |
Step 2: Configuring the GitHub Actions Workflow
This workflow triggers when a change occurs in the tokens/ path on the figma-tokens branch.
# .github/workflows/sync-tokens.yml
name: Sync Design Tokens
on:
push:
branches:
- figma-tokens
paths:
- 'tokens/**'
jobs:
build-and-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# peter-evans/create-pull-request detects changes using the full
# git history, so it may fail with a shallow clone
- uses: pnpm/action-setup@v4
with:
version: latest
- name: Install dependencies
run: pnpm install
- name: Transform tokens with Style Dictionary
run: pnpm build:tokens
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GH_PAT }}
# Use GH_PAT, not secrets.GITHUB_TOKEN.
# PRs created with the default token will not trigger subsequent
# workflows due to GitHub policy, leaving the pipeline half-functional.
branch: tokens/update-${{ github.run_number }}
base: main
title: "🎨 Design Token Update"
body: |
A design token change was detected from Tokens Studio.
- Changed tokens: see `tokens/` directory
- Generated CSS variables: see `dist/` directory
commit-message: "chore: sync design tokens from Figma"| Key Setting | Role |
|---|---|
paths: - 'tokens/**' |
Restricts scope so the workflow doesn't run on non-token file changes |
branch: tokens/update-${{ github.run_number }} |
Prevents PR conflicts with a unique branch name on every run |
secrets.GH_PAT |
Register a Personal Access Token with PR creation permissions in repository Secrets |
Step 3: Generating Code with Style Dictionary + sd-transforms
First, install the dependencies.
pnpm add -D style-dictionary @tokens-studio/sd-transformsSince the primary users of this pipeline are the frontend team, we'll focus on generating CSS variables and a Tailwind CSS v4 config.
// style-dictionary.config.mjs
// Runs in a Node.js 18+ ESM environment.
// "type": "module" must be set in package.json.
import StyleDictionary from 'style-dictionary';
import { registerTransforms } from '@tokens-studio/sd-transforms';
// Converts the reference syntax and format differences in Tokens Studio JSON
// into a format Style Dictionary can understand.
// Without this call, references like {color.brand.primary} will be output as strings.
registerTransforms(StyleDictionary);
const sd = new StyleDictionary({
source: ['tokens/**/*.json'],
platforms: {
css: {
// The 'tokens-studio' transformGroup is a group registered by registerTransforms.
// It includes essential frontend transforms like color format conversion and reference resolution.
// When adding custom platforms, extend from this value as your baseline.
transformGroup: 'tokens-studio',
prefix: 'ds',
buildPath: 'dist/css/',
files: [{
destination: 'variables.css',
format: 'css/variables',
}],
},
tailwind: {
transformGroup: 'tokens-studio',
buildPath: 'dist/',
files: [{
destination: 'tailwind.tokens.js',
format: 'javascript/module',
}],
},
},
});
// buildAllPlatforms is an async function, so await is required.
await sd.buildAllPlatforms();Add the script to package.json.
{
"type": "module",
"scripts": {
"build:tokens": "node style-dictionary.config.mjs"
},
"devDependencies": {
"style-dictionary": "^4.0.0",
"@tokens-studio/sd-transforms": "^1.0.0"
}
}With the above configuration, CSS variables and a Tailwind token file are generated simultaneously from a single JSON under tokens/.
Pros and Cons
Advantages
| Item | Description |
|---|---|
| Eliminates design-code drift | Designers and developers share the same JSON as a single source of truth, structurally preventing color value mismatches |
| Platform-agnostic output | A single JSON can simultaneously generate CSS variables, a Tailwind config, Android XML, and Swift constants |
| Review process built in | Token changes go through the same PR-based review and approval process as code changes |
| Leverages existing infrastructure | Built entirely on GitHub Actions with no separate SaaS, so no additional cost |
| Bidirectional sync | Supports both exporting to and importing from Figma Variables via Tokens Studio |
Disadvantages and Caveats
| Item | Description | Mitigation |
|---|---|---|
| Figma Variables type limitation | Of 23 token types, only 4 (Color, Number, String, Boolean) can be exported as Variables | Manage typography and effects separately as Figma Styles |
| Variables count limit | Maximum of 5,000 per collection; excess is silently omitted | Distribute token structure across multiple collections |
| Mode count limitation | Free plan supports only 1 mode per collection | Multi-brand systems require a Professional plan or higher |
| Pro feature restrictions | Some advanced GitHub integration features like multi-file sync require a Tokens Studio Pro license | Starting with a single-file structure allows building the basic pipeline on the free plan |
| Variables REST API limitations | Write (POST/PUT) functionality for the Figma Variables REST API is Enterprise-only. Read (GET) is available on Free/Pro | Can be substituted with Tokens Studio plugin-based sync |
| Learning curve | Requires understanding Tokens Studio Sets & Themes concepts, GitHub Actions YAML, and sd-transforms configuration | Starting with the plugin-examples starter template lowers the barrier to entry |
The Most Common Mistakes in Practice
-
Setting the Tokens Studio sync branch to
main— The designer's changes are applied directly tomainwithout review, breaking the review process. Using a dedicated branch likefigma-tokensis strongly recommended. -
Creating PRs with
secrets.GITHUB_TOKEN— GitHub has a policy where PRs created with the default token will not trigger subsequent workflows (e.g., automatic CI runs). You must generate a separateGH_PAT(Personal Access Token) and register it in Secrets for the entire pipeline to function correctly. -
Directly modifying values in the Figma Variables panel — If a designer changes a color directly in the Variables panel, it won't sync with Tokens Studio's JSON, and the change may be overwritten on the next push. Changes must always originate from the Tokens Studio plugin UI.
Closing Thoughts
The Tokens Studio + Style Dictionary + GitHub Actions pipeline is a structural solution that absorbs design changes into a code review process rather than manual handoffs. Once built, designers can update tokens across all platforms with a single sync button click in the plugin, and developers with a single PR review. That said, there are areas this pipeline doesn't cover. Structural changes at the component level and handling token deletions require separate migration work — keep this in mind when scoping your adoption.
Three steps you can take right now:
-
Install the Tokens Studio plugin and configure your token sets — Install "Tokens Studio for Figma" from the Figma Community, then connect your GitHub repository and a dedicated
figma-tokensbranch under Settings → Token Storage. If you don't have atokens/folder to start, you can grab sample token JSON from the plugin-examples starter template. -
Write
style-dictionary.config.mjsand verifypnpm build:tokensruns locally — Add the dependencies withpnpm add -D style-dictionary @tokens-studio/sd-transforms, and using the example config above as a reference, confirm thatdist/css/variables.cssis generated correctly locally first. -
Add
.github/workflows/sync-tokens.ymland do a test push — Add the Actions example above to your.github/workflows/directory, register theGH_PATsecret, then modify a single token in Tokens Studio and press the sync button. Shortly after, you should see a PR automatically created in your repository.
Next article: How to use Tokens Studio's Sets and Themes features to manage Light/Dark mode and multi-brand tokens simultaneously with a single pipeline
References
Official Documentation
- GitHub - Git Sync Provider | Tokens Studio Official Docs
- Integrating with GitHub Actions | Tokens Studio Official Docs
- Variables and Tokens Studio Overview | Tokens Studio Official Docs
- Style Dictionary V4 release plans | Tokens Studio Blog
- GitHub - tokens-studio/sd-transforms
- GitHub - figma/variables-github-action-example (Official Figma)
Starter Templates
Case Studies and Tutorials
- How We Cut UI Development Time in Half with Figma and Token Studio | Smallstep
- Syncing Figma Variables and Style Dictionary with GitHub Actions | James Ives
- Building a Figma to GitHub token pipeline that actually works | DEV Community
- Design Tokens in Practice: From Figma Variables to Production Code | Design Systems Collective
- Getting your head around Figma Variables, Figma Styles and Tokens Studio | Specify
- Automating design systems with Figma Variables REST API | Medium