Tokens Studio + Style Dictionary + GitHub Actions로 디자인 토큰 변경을 PR로 자동화하기
디자이너가 Figma에서 버튼 색상을 #3B82F6으로 바꿨는데, 개발자 코드에는 여전히 #3B82F5가 남아 있다면 어떨까요? 수동으로 색상값을 복사해 붙여넣고, Slack으로 "방금 토큰 바꿨어요" 메시지를 보내고, 개발자가 직접 CSS 파일을 수정하는 반복 작업은 팀 규모가 커질수록 실수와 지연을 낳습니다. 대안이 없는 건 아닙니다. CSS Variables를 직접 관리하거나, Supernova·Specify 같은 SaaS 솔루션을 도입하는 방법도 있습니다. 그러나 기존 GitHub 워크플로우와 자연스럽게 통합되고, 오픈소스 도구만으로 구축 가능하며, PR 리뷰 프로세스까지 내재화되는 방식을 찾는다면 이 글에서 소개하는 파이프라인이 가장 현실적인 선택입니다.
이 글에서는 Tokens Studio 플러그인이 Figma 변경 사항을 GitHub에 자동으로 푸시하고, GitHub Actions가 Style Dictionary와 sd-transforms로 플랫폼별 코드를 생성한 뒤 Pull Request까지 자동으로 만들어주는 엔드투엔드 파이프라인 구성 방법을 단계별로 소개합니다. Smallstep 팀이 이 파이프라인 도입 후 UI 개발 시간을 절반으로 단축했다고 보고된 바 있으며, 이 구조는 이미 여러 조직에서 검증된 표준 아키텍처입니다. 각 레이어가 어떤 역할을 하는지, 실제로 어떻게 설정하는지, 그리고 흔히 빠지는 함정은 무엇인지까지 실전 관점에서 다룹니다.
핵심 개념
드리프트(Drift): 시스템의 두 부분(여기서는 디자인과 코드)이 시간이 지남에 따라 서로 달라지는 현상입니다. 이 파이프라인의 핵심 목적은 드리프트를 구조적으로 방지하는 것입니다.
세 레이어의 역할 분담
TL;DR: Tokens Studio가 JSON을 GitHub에 올리면, Style Dictionary가 플랫폼별 코드로 변환하고, GitHub Actions가 PR을 만들어줍니다.
이 파이프라인은 세 개의 독립적인 레이어가 유기적으로 연결되어 동작합니다.
| 레이어 | 도구 | 역할 |
|---|---|---|
| 토큰 관리 | Tokens Studio (Figma 플러그인) | 디자인 토큰 정의·관리, GitHub 양방향 동기화 |
| 캔버스 표현 | Figma Variables | Tokens Studio 결과물을 Figma 캔버스에서 사용 가능한 형태로 표현 |
| 코드 변환 | GitHub Actions + Style Dictionary | JSON → 플랫폼별 코드 변환 및 PR 자동 생성 |
전체 흐름을 한 줄로 요약하면 다음과 같습니다.
디자이너 (Tokens Studio에서 토큰 수정)
→ Tokens Studio가 figma-tokens 브랜치에 JSON 푸시
→ GitHub Actions 트리거
→ Style Dictionary + sd-transforms가 CSS 변수·Tailwind config 등 생성
→ peter-evans/create-pull-request가 main으로 PR 자동 생성Tokens Studio vs Figma Variables — 경쟁이 아닌 역할 분담
많은 분들이 "Tokens Studio를 쓰면 Figma Variables는 필요 없는 것 아닌가요?"라고 질문합니다. 결론부터 말씀드리면, 둘은 경쟁 관계가 아니라 역할이 명확히 다릅니다.
핵심 원칙: Tokens Studio가 시스템의 단일 진실 공급원(Single Source of Truth, SSOT) 이고, Figma Variables는 그 결과물을 캔버스에서 사용 가능한 형태로 표현(output) 하는 레이어입니다. 변경은 반드시 Tokens Studio에서 시작해야 합니다.
Figma Variables를 직접 편집하면 Tokens Studio의 JSON과 Figma 캔버스 사이에 드리프트가 발생합니다. 한 가지 중요한 제약도 알아두시면 좋습니다. Tokens Studio가 지원하는 23종의 토큰 타입 중 Figma Variables는 Color, Number, String, Boolean 4종만 지원합니다. 타이포그래피나 이펙트 토큰은 Figma Styles로만 처리됩니다.
W3C DTCG 표준과 sd-transforms가 필요한 이유
TL;DR: Tokens Studio JSON과 W3C 표준 형식은 미묘하게 다릅니다. sd-transforms가 그 간극을 메워줍니다.
2024~2025년 사이 가장 중요한 변화 중 하나는 W3C Design Token Community Group(DTCG) 표준 채택입니다. Style Dictionary v4가 정식 출시되면서 토큰 JSON 형식이 $value, $type 키를 사용하는 표준 형식으로 자리잡고 있습니다.
// W3C DTCG 표준 형식
{
"color": {
"brand": {
"primary": {
"$value": "#3B82F6",
"$type": "color",
"$description": "주 브랜드 색상"
}
}
}
}반면 Tokens Studio가 내보내는 JSON은 아래처럼 형식이 다릅니다.
// Tokens Studio 내보내기 형식
{
"color": {
"brand": {
"primary": {
"value": "{color.palette.blue.500}",
"type": "color"
}
}
}
}두 형식의 차이는 두 가지입니다. $value/$type 대신 value/type을 쓰고, 값 참조 구문({color.palette.blue.500})이 Style Dictionary의 기본 파싱 규칙과 다릅니다. @tokens-studio/sd-transforms 패키지의 registerTransforms() 함수가 이 두 가지 차이를 Style Dictionary가 이해할 수 있는 형식으로 변환해주는 역할을 합니다. 이 호출을 빠뜨리면 참조 구문이 그대로 문자열로 출력되거나 빌드가 실패합니다.
실전 적용
개념을 이해했으니, 이제 실제로 어떻게 설정하는지 살펴보겠습니다. 세 단계로 나눠 순서대로 따라가시면 됩니다.
Step 1: Tokens Studio에서 GitHub 브랜치 연결하기
Figma에서 Tokens Studio 플러그인을 열고 Settings → Token Storage → Add new credentials 경로로 진입합니다.
Provider: GitHub
Repository: your-org/design-system
Branch: figma-tokens ← main이 아닌 전용 브랜치로 설정하는 것이 핵심
File Path: tokens/
Token: ghp_xxxxxxxxxxxx ← GitHub Personal Access Token (repo 권한)GitHub Personal Access Token(PAT)은 GitHub → Settings → Developer settings → Personal access tokens에서 발급할 수 있습니다. repo 권한 하나만 체크하면 충분합니다. 백엔드 개발자분들께는 생소할 수 있지만, 이 토큰이 Tokens Studio 플러그인이 GitHub 리포지토리에 파일을 푸시할 수 있게 해주는 인증 수단입니다.
여기서 브랜치를 figma-tokens처럼 별도 브랜치로 설정하는 것이 이 파이프라인의 핵심 설계입니다. 플러그인이 이 브랜치에 JSON을 푸시하면, GitHub Actions가 자동으로 main으로의 PR을 생성하는 구조입니다. main에 직접 푸시하도록 설정하면 리뷰 프로세스를 우회하게 됩니다.
| 설정 항목 | 권장값 | 이유 |
|---|---|---|
| Branch | figma-tokens |
Actions 트리거 분리 및 리뷰 프로세스 확보 |
| File Path | tokens/ |
Style Dictionary source 경로와 일치 필요 |
| Token | repo 권한 PAT | push 권한 필요 |
Step 2: GitHub Actions 워크플로우 구성하기
figma-tokens 브랜치의 tokens/ 경로에 변경이 발생하면 트리거되는 워크플로우입니다.
# .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는 전체 git 히스토리로
# 변경 감지를 수행하므로 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 }}
# secrets.GITHUB_TOKEN이 아닌 GH_PAT를 써야 합니다.
# 기본 토큰으로 PR을 생성하면 GitHub 정책상 후속 워크플로우가
# 트리거되지 않아 파이프라인이 절반만 동작합니다.
branch: tokens/update-${{ github.run_number }}
base: main
title: "🎨 디자인 토큰 업데이트"
body: |
Tokens Studio에서 디자인 토큰 변경이 감지됐습니다.
- 변경된 토큰: `tokens/` 디렉토리 확인
- 생성된 CSS 변수: `dist/` 디렉토리 확인
commit-message: "chore: sync design tokens from Figma"| 주요 설정 | 역할 |
|---|---|
paths: - 'tokens/**' |
토큰 파일 외 변경에는 워크플로우가 실행되지 않도록 범위 제한 |
branch: tokens/update-${{ github.run_number }} |
매 실행마다 고유한 브랜치명으로 PR 충돌 방지 |
secrets.GH_PAT |
PR 생성 권한이 있는 Personal Access Token을 리포지토리 Secrets에 등록 |
Step 3: Style Dictionary + sd-transforms로 코드 생성하기
먼저 의존성을 설치합니다.
pnpm add -D style-dictionary @tokens-studio/sd-transforms이 파이프라인의 주요 사용자가 프론트엔드 팀이므로, CSS 변수와 Tailwind CSS v4 config 생성을 중심으로 구성합니다.
// style-dictionary.config.mjs
// Node.js 18+ ESM 환경에서 실행됩니다.
// package.json에 "type": "module"이 설정되어 있어야 합니다.
import StyleDictionary from 'style-dictionary';
import { registerTransforms } from '@tokens-studio/sd-transforms';
// Tokens Studio JSON의 참조 구문과 형식 차이를
// Style Dictionary가 이해할 수 있도록 변환합니다.
// 이 호출 없이는 {color.brand.primary} 같은 참조가 문자열로 출력됩니다.
registerTransforms(StyleDictionary);
const sd = new StyleDictionary({
source: ['tokens/**/*.json'],
platforms: {
css: {
// 'tokens-studio' transformGroup은 registerTransforms가 등록한
// 그룹으로, 색상 형식 변환·참조 해석 등 프론트엔드 필수 변환을 포함합니다.
// 커스텀 플랫폼을 추가할 때도 이 값을 기준으로 확장하면 됩니다.
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는 비동기 함수이므로 await가 필요합니다.
await sd.buildAllPlatforms();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"
}
}위 설정이 실행되면 tokens/ 아래의 JSON 하나에서 CSS 변수와 Tailwind 토큰 파일이 동시에 생성됩니다.
장단점 분석
장점
| 항목 | 내용 |
|---|---|
| 디자인-코드 드리프트 제거 | 디자이너와 개발자가 동일한 JSON을 단일 진실 공급원으로 공유해 색상값 불일치가 구조적으로 방지됩니다 |
| 플랫폼 무관 배포 | 하나의 JSON에서 CSS 변수, Tailwind config, Android XML, Swift 상수를 동시에 생성할 수 있습니다 |
| 변경 리뷰 프로세스 내재화 | 토큰 변경도 코드 변경처럼 PR 기반 리뷰·승인 과정을 거치게 됩니다 |
| 기존 인프라 활용 | 별도 SaaS 없이 GitHub Actions만으로 구성되어 추가 비용이 없습니다 |
| 양방향 동기화 | Tokens Studio ↔ Figma Variables 간 내보내기·가져오기를 모두 지원합니다 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| Figma Variables 타입 제한 | 23종 토큰 중 4종(Color, Number, String, Boolean)만 Variables로 내보낼 수 있습니다 | 타이포그래피·이펙트는 Figma Styles로 별도 관리합니다 |
| Variables 개수 한계 | 컬렉션당 최대 5,000개로 초과분은 자동 생략됩니다 | 토큰 구조를 여러 컬렉션으로 분산해 관리합니다 |
| 모드 수 제한 | Free 플랜은 컬렉션당 1개 모드만 지원합니다 | 멀티브랜드 시스템은 Professional 이상 플랜이 필요합니다 |
| Pro 기능 제약 | 멀티 파일 동기화 등 일부 고급 GitHub 연동 기능은 Tokens Studio Pro 라이선스가 필요합니다 | 단일 파일 구조로 시작하면 무료 플랜에서도 기본 파이프라인 구축이 가능합니다 |
| Variables REST API 제약 | Figma Variables REST API의 쓰기(POST/PUT) 기능은 Enterprise 전용입니다. 읽기(GET)는 Free/Pro도 사용 가능합니다 | Tokens Studio 플러그인 기반 동기화로 대체할 수 있습니다 |
| 학습 곡선 | Tokens Studio Sets·Themes 개념, GitHub Actions YAML, sd-transforms 설정을 모두 이해해야 합니다 | plugin-examples 스타터 템플릿으로 시작하면 진입 장벽을 낮출 수 있습니다 |
실무에서 가장 흔한 실수
-
Tokens Studio 동기화 브랜치를
main으로 설정하는 경우 — 디자이너의 변경이 리뷰 없이 바로main에 반영되어 리뷰 프로세스가 무너집니다.figma-tokens처럼 별도 브랜치를 사용하는 것을 권장합니다. -
secrets.GITHUB_TOKEN으로 PR을 생성하는 경우 — GitHub의 기본 토큰으로 생성된 PR은 후속 워크플로우(예: CI 자동 실행)가 트리거되지 않는 GitHub 정책이 있습니다.GH_PAT(Personal Access Token)를 별도로 발급해 Secrets에 등록해야 파이프라인 전체가 정상 동작합니다. -
Figma Variables 패널에서 직접 값을 수정하는 경우 — 디자이너가 Variables 패널에서 색상을 직접 바꾸면 Tokens Studio JSON과 동기화되지 않아 다음 푸시 시점에 변경이 덮어씌워질 수 있습니다. 변경은 반드시 Tokens Studio 플러그인 UI에서 시작해야 합니다.
마치며
Tokens Studio + Style Dictionary + GitHub Actions 파이프라인은 디자인 변경을 수동 전달이 아닌 코드 리뷰 프로세스로 흡수하는 구조적 해결책입니다. 한 번 구축하면 디자이너는 플러그인 동기화 버튼 한 번으로, 개발자는 PR 리뷰 한 번으로 전체 플랫폼의 토큰이 업데이트되는 환경을 누릴 수 있습니다. 다만 이 파이프라인이 해결하지 못하는 영역도 있습니다. 컴포넌트 단위의 구조적 변경이나 토큰 삭제 처리는 별도 마이그레이션 작업이 필요하며, 이 점을 감안하고 도입 범위를 설계하는 것을 권장합니다.
지금 바로 시작해볼 수 있는 3단계:
-
Tokens Studio 플러그인 설치 및 토큰 세트 구성 — Figma Community에서 "Tokens Studio for Figma"를 설치한 뒤, Settings → Token Storage에서 GitHub 리포지토리와
figma-tokens전용 브랜치를 연결해보시면 좋습니다. 시작 시tokens/폴더가 없다면 plugin-examples 스타터 템플릿에서 샘플 토큰 JSON을 가져올 수 있습니다. -
style-dictionary.config.mjs작성 및pnpm build:tokens로컬 실행 확인 —pnpm add -D style-dictionary @tokens-studio/sd-transforms명령으로 의존성을 추가하고, 위 예시 설정을 참고해dist/css/variables.css가 정상 생성되는지 로컬에서 먼저 확인하는 것을 권장합니다. -
.github/workflows/sync-tokens.yml추가 및 테스트 푸시 — 위 Actions 예시를.github/workflows/디렉토리에 추가하고GH_PAT시크릿을 등록한 뒤, Tokens Studio에서 토큰 하나를 수정해 동기화 버튼을 눌러보시면 됩니다. 잠시 후 리포지토리에 자동으로 PR이 생성되는 것을 확인하실 수 있습니다.
다음 글: Tokens Studio의 Sets와 Themes 기능을 활용해 하나의 파이프라인으로 Light/Dark 모드와 멀티브랜드 토큰을 동시에 관리하는 방법
참고 자료
공식 문서
- GitHub - Git Sync Provider | Tokens Studio 공식 문서
- Integrating with GitHub Actions | Tokens Studio 공식 문서
- Variables and Tokens Studio Overview | Tokens Studio 공식 문서
- Style Dictionary V4 release plans | Tokens Studio 블로그
- GitHub - tokens-studio/sd-transforms
- GitHub - figma/variables-github-action-example (Figma 공식)
스타터 템플릿
실전 사례 및 튜토리얼
- 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