| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- scroll
- IntersectionObserver
- 스크롤
- 객체
- 이벤트
- dom
- event
- video
- input
- 문자열
- This
- map
- array
- json
- Promise
- object
- 애니메이션
- 이벤트 루프
- ios
- ES6
- ajax
- 클로저
- 비동기
- slice
- Push
- Flex
- animation
- 모듈
- 배열
- 이벤트 위임
- Today
- Total
FEDev Story
디자인 시스템의 전체 자동화 파이프라인(SSOT 체인) 본문

1. 여기서 말하는 "토큰"이란
일반적으로 토큰(Token)은 "최소 단위"라는 뜻입니다. 디자인 토큰(Design Token) 은 디자이너와 개발자가 함께 사용하는 UI의 최소 디자인 값에 붙인 이름표입니다.
예를 들어 "파란색 버튼의 배경색"은 #3B82F6 이라는 값보다 color.primary.500 이라는 이름으로 관리합니다. 값이 바뀌어도 이름만 그대로 쓰면 되니까요.
색상, 폰트 크기, 간격, 둥근 모서리, 그림자 — 이 모든 반복되는 값들을 이름 붙여 관리하는 것이 토큰입니다.
2. 디자인 토큰을 코드로 "매핑"한다는 뜻
공고에서 말하는 흐름은 이겁니다:
Figma 디자인 스펙
↓
CSS Variables ← 브라우저가 이해하는 변수
↓
tailwind.config.js ← Tailwind가 이 변수를 클래스로 활용
↓
컴포넌트 코드 ← 개발자가 className="bg-primary-500" 으로 사용
매핑(Mapping) 이란 Figma에서 디자이너가 정의한 값과 실제 코드의 변수를 1:1로 연결하는 작업입니다.
3. 실제 예시로 전체 흐름 보기
Step 1 — Figma에서 디자이너가 정의
Figma Variables 패널에서 이렇게 만들어 둡니다:
Collection: color
├── primary/500 = #3B82F6
├── primary/600 = #2563EB
├── gray/100 = #F1F5F9
└── gray/900 = #0F172A
Collection: spacing
├── sm = 8px
├── md = 16px
└── lg = 24px
Collection: radius
└── button = 6px
Step 2 — CSS Variables로 변환
/* tokens.css */
:root {
/* color tokens */
--color-primary-500: #3B82F6;
--color-primary-600: #2563EB;
--color-gray-100: #F1F5F9;
--color-gray-900: #0F172A;
/* spacing tokens */
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
/* radius tokens */
--radius-button: 6px;
}
Step 3 — tailwind.config.js에 토큰 매핑
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
primary: {
500: 'var(--color-primary-500)', // CSS 변수 연결!
600: 'var(--color-primary-600)',
},
gray: {
100: 'var(--color-gray-100)',
900: 'var(--color-gray-900)',
}
},
spacing: {
sm: 'var(--spacing-sm)',
md: 'var(--spacing-md)',
lg: 'var(--spacing-lg)',
},
borderRadius: {
button: 'var(--radius-button)',
}
}
}
}
Step 4 — 컴포넌트에서 사용
// Button.tsx
<button className="bg-primary-500 hover:bg-primary-600 px-md rounded-button">
클릭
</button>
4. SSOT 체인이 왜 중요한가?
공고에서 "SSOT 체인 유지" 라고 한 부분이 핵심입니다. SSOT는 Single Source of Truth, 즉 진실의 단일 출처입니다.
❌ SSOT가 없을 때 (흔한 문제)
Figma에서 파란색을 #2563EB로 바꿈
→ 디자이너만 알고 있음
→ 개발자는 여전히 #3B82F6 사용 중
→ 버튼 색이 디자인과 다름
→ QA에서 발견 → 개발자가 다시 수정
→ 반복...
✅ SSOT 체인이 있을 때
Figma Variable 값만 바꾸면
→ tokens.css 자동 업데이트
→ tailwind.config 자동 반영
→ 모든 컴포넌트 색상 자동 변경
→ 디자이너·개발자 항상 동기화
5. 공고의 토큰 규모 해석
공고에서 "토큰 규모: 색상 79+, 타이포 18, 스페이싱 18, 반경 11, 그림자 7" 이라고 나옵니다.
색상 79개 이상 → primary, secondary, gray, success, warning...
각각 50/100/200/.../900 단계별로 정의
타이포 18개 → font-size, font-weight, line-height, letter-spacing 조합
예: text-sm, text-md, text-lg, text-display...
스페이싱 18개 → 4px 단위로 4/8/12/16/20/24/32/48/64... 등
반경 11개 → none/sm/md/lg/xl/full 등
그림자 7개 → sm/md/lg + 컬러별 변형
이 규모는 꽤 큰 디자인 시스템입니다. 중견 이상 회사에서 다수 서비스를 운영할 때 이 정도 토큰 체계를 갖춥니다.
6. Figma와의 관계
Figma에는 Variables(변수)와 Tokens(토큰) 기능이 있어서 디자이너가 Figma 안에서 직접 토큰을 정의하고, 이걸 JSON으로 내보낼 수 있습니다.
Figma Variables → export → tokens.json → 변환 도구 → CSS Variables
공고의 "Figma Inspect를 열면 '이건 토큰 A, 이건 시멘틱 B'가 바로 읽히는 분"이라는 핵심역량은, Figma에서 컴포넌트를 클릭했을 때 색상값(#3B82F6)이 아니라 토큰 이름(color.primary.500)이 보이는 상태를 구축하고 읽을 수 있는 사람을 원하는 겁니다.
7. 현재 만들고 계신 컴포넌트 가이드와의 연결점
지금 작업 중인 UI 컴포넌트 가이드의 tokens.css가 바로 이 디자인 토큰 레이어입니다. 공고의 요구사항과 지금 PRD의 설계 방향이 상당히 일치하고 있어요.
공고의 파이프라인 현재 PRD 설계
─────────────────────────────────────────
Figma Variables = (수동 정의 단계)
↓
tokens.json = tokens.css
↓
CSS Variables = tokens.css의 :root 변수들
↓
tailwind.config.js = (순수 CSS라 불필요)
↓
컴포넌트 코드 = components/button.css 등
다크/라이트 모드를 [data-theme="dark"] 로 전환하는 방식도 이 공고에서 요구하는 "CSS Variables 기반 3개 브랜드 테마 전환"과 동일한 원리입니다. 잘 만들어두면 포트폴리오로도 충분히 활용할 수 있는 수준입니다! 🚀
SSOT 체인
SSOT 체인의 핵심은 "사람이 중간에 개입하지 않아도 자동으로 동기화되는 파이프라인" 입니다.
전체 자동화 파이프라인 구조
┌─────────────────────────────────────────────────────────────────┐
│ Figma │
│ Variables 패널에서 디자이너가 값 수정 │
└────────────────────┬────────────────────────────────────────────┘
│ ① Figma Plugin (export)
▼
┌─────────────────────────────────────────────────────────────────┐
│ tokens.json / tokens.json (Style Dictionary 형식) │
│ { │
│ "color": { │
│ "primary": { "500": { "value": "#3B82F6" } } │
│ } │
│ } │
└────────────────────┬────────────────────────────────────────────┘
│ ② 변환 도구 (Transform Tool)
▼
┌─────────────────────────────────────────────────────────────────┐
│ tokens.css / tokens.scss / tokens.js / tokens.ts ... │
│ :root { │
│ --color-primary-500: #3B82F6; │
│ } │
└────────────────────┬────────────────────────────────────────────┘
│ ③ tailwind.config.js 참조
▼
┌─────────────────────────────────────────────────────────────────┐
│ 컴포넌트 코드 │
│ <button class="bg-primary-500"> │
└─────────────────────────────────────────────────────────────────┘
① Figma → JSON: 익스포트 플러그인
Figma에서 직접 Variables/Styles를 JSON으로 내보내는 플러그인들입니다.
Tokens Studio (구 Figma Tokens) — 업계 표준
설치: Figma 플러그인 마켓 → "Tokens Studio"
특징: 가장 널리 쓰이는 도구
출력: W3C Design Token 포맷 또는 Style Dictionary 포맷
// 출력 예시: tokens.json
{
"global": {
"color": {
"primary": {
"500": {
"value": "#3B82F6",
"type": "color",
"description": "주요 버튼, 링크 색상"
}
}
},
"spacing": {
"md": {
"value": "16",
"type": "spacing"
}
}
}
}
GitHub와 연동하면 디자이너가 Figma에서 값을 바꾸고 "Push to GitHub" 버튼 하나로 PR이 자동 생성됩니다.
Figma 공식 Variables API (2023년 이후)
Figma가 공식으로 Variables REST API를 열어둠
→ 플러그인 없이 API로 직접 토큰 값 읽기 가능
→ CI/CD에서 직접 Figma API 호출 → JSON 자동 생성
// Figma API 호출 예시
const response = await fetch(
`https://api.figma.com/v1/files/${FILE_KEY}/variables/local`,
{ headers: { 'X-Figma-Token': FIGMA_TOKEN } }
);
② JSON → CSS/JS: 변환 도구
Style Dictionary (Amazon 오픈소스) — 가장 유명
npm install -g style-dictionary
// sd.config.json — 변환 규칙 정의
{
"source": ["tokens/**/*.json"],
"platforms": {
"css": {
"transformGroup": "css",
"prefix": "c",
"buildPath": "dist/",
"files": [{
"destination": "tokens.css",
"format": "css/variables"
}]
},
"js": {
"transformGroup": "js",
"buildPath": "dist/",
"files": [{
"destination": "tokens.js",
"format": "javascript/es6"
}]
}
}
}
style-dictionary build
/* 자동 생성된 tokens.css */
:root {
--c-color-primary-500: #3B82F6;
--c-spacing-md: 16px;
--c-radius-button: 6px;
}
/* 자동 생성된 tokens.js */
export const COLOR_PRIMARY_500 = '#3B82F6';
export const SPACING_MD = '16px';
하나의 JSON 소스에서 CSS, JS, iOS Swift, Android XML 등 여러 플랫폼용 파일을 동시에 생성하는 게 핵심 강점입니다.
Theo (Salesforce 오픈소스)
Style Dictionary보다 가볍고 단순한 변환 도구로, 소규모 프로젝트에 적합합니다.
# tokens.yml
global:
color:
primary: '#3B82F6'
theo tokens.yml --transform web --format custom-properties
# → --color-primary: #3B82F6;
Token Pipeline (W3C 표준 기반 신흥)
2024년 이후 W3C에서 Design Token 포맷을 공식 표준화하면서 생긴 도구 생태계로, @cobalt-ui/cli, @token-alchemy 등이 있습니다.
③ 전체 자동화 완성: CI/CD 연결
변환 도구까지만 있으면 "반자동"입니다. 완전 자동화는 GitHub Actions 같은 CI/CD에 연결할 때 완성됩니다.
# .github/workflows/sync-tokens.yml
name: Sync Design Tokens
on:
# Figma Webhook 또는 수동 트리거
workflow_dispatch:
push:
paths:
- 'tokens/**/*.json' # tokens.json 변경 시 자동 실행
jobs:
build-tokens:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: npm ci
- name: Build tokens (JSON → CSS/JS)
run: npx style-dictionary build
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
title: '🎨 디자인 토큰 자동 업데이트'
body: 'Figma에서 변경된 토큰이 자동으로 반영되었습니다.'
branch: 'auto/design-tokens'
이렇게 되면 전체 흐름이 이렇게 됩니다:
디자이너 Figma에서 파란색 #3B82F6 → #2563EB 변경
↓ (Tokens Studio "Push to GitHub")
tokens.json PR 생성
↓ (GitHub Actions 자동 실행)
Style Dictionary가 CSS/JS 파일 자동 재생성
↓ (PR 머지)
모든 컴포넌트 색상 자동 변경
↓
개발자 개입 0
"개발자 개입 0"이라고 했는데, 실제 실무에서는 PR 머지 단계에서 개발자(또는 리드)의 승인이 한 번 들어갑니다. 완전 무인 자동화도 기술적으로 가능하지만, 토큰 변경이 예상치 못한 곳에서 UI를 깨뜨릴 수 있어서 대부분의 팀이 이 한 단계는 유지합니다.
전체 흐름을 정리하면 이렇습니다:
┌─────────────────────────────────────────────────┐
│ 👩🎨 디자이너 (Figma) │
│ │
│ Variables 패널에서 색상 변경 │
│ #3B82F6 → #2563EB │
│ │
│ Tokens Studio 플러그인 │
│ → "Push to GitHub" 클릭 │
└──────────────────────┬──────────────────────────┘
│ tokens.json 자동 커밋
▼
┌─────────────────────────────────────────────────┐
│ GitHub Repository │
│ │
│ PR 자동 생성 │
│ "🎨 디자인 토큰 자동 업데이트" │
│ │
│ GitHub Actions 자동 실행 │
│ → Style Dictionary build │
│ → tokens.css / tokens.js 자동 재생성 │
│ → PR에 파일 추가 │
└──────────────────────┬──────────────────────────┘
│ ← 여기만 개발자 개입
▼
┌─────────────────────────────────────────────────┐
│ 👨💻 개발자 (PR 리뷰) │
│ │
│ 변경된 토큰 diff 확인 │
│ - --color-primary-500: #3B82F6 → #2563EB │
│ │
│ 문제 없으면 "Merge" 승인 │
└──────────────────────┬──────────────────────────┘
│ 머지 완료
▼
┌─────────────────────────────────────────────────┐
│ 👨💻 개발자 (로컬) │
│ │
│ git pull │
│ → 변경된 tokens.css 동기화 │
│ → 모든 컴포넌트 색상 자동 반영 │
│ → 추가 코드 수정 없음 ✅ │
└─────────────────────────────────────────────────┘
기존 방식과 비교하면 차이가 명확합니다
❌ SSOT 이전 (수동)
디자이너: "버튼 파란색 #2563EB로 바꿨어요"
↓ (슬랙 메시지 or 구두 전달)
개발자: 디자이너한테 물어보거나 Figma 직접 확인
↓
개발자: button.css 열어서 색상 직접 수정
↓
개발자: 다른 컴포넌트에도 같은 색 쓰는 곳 찾아서 수정
↓
개발자: 커밋 → 푸시
↓
QA: 디자인과 실제 색상 일치 확인... 혹시 빠진 곳은?
소요시간: 30분 ~ 수 시간
실수 가능성: 높음 (빠뜨린 컴포넌트 발생)
✅ SSOT 이후 (자동)
디자이너: Figma에서 토큰 값 변경 → Push 클릭
개발자: PR 확인 → diff 2줄 → Merge → git pull
소요시간: 5분
실수 가능성: 없음 (토큰 참조하는 모든 곳 자동 반영)
핵심을 한 문장으로
디자이너가 Figma에서 값을 바꾸면, 개발자는 코드를 한 줄도 건드리지 않고 PR 승인 + git pull 만으로 모든 컴포넌트에 반영된다.
이게 바로 공고에서 말한 "SSOT 체인 유지" 의 실체입니다. 그래서 이 파이프라인을 구축하고 운영할 수 있는 개발자를 채용하려는 거고, 꽤 고급 스킬로 평가받는 영역입니다 🙂
PR(Pull Request)란?
한마디로 "내가 만든 코드 변경사항을 메인 코드에 합쳐도 될까요? 검토해 주세요!" 라고 요청하는 것입니다.
일상에 비유하면 이렇습니다:
회사 문서 작업에 비유하면
기존 방식 (PR 없음)
→ 직원이 공유 문서를 바로 수정
→ 실수해도 아무도 모름
→ 잘못된 내용이 그대로 배포
PR 방식
→ 직원이 문서 사본에 수정안 작성
→ "이렇게 바꾸면 어떨까요?" 팀장에게 제출
→ 팀장이 검토 후 "승인" or "수정 요청"
→ 승인되면 원본 문서에 반영
GitHub에서 PR의 실제 흐름
main 브랜치 (원본 코드, 항상 안정적)
│
├── 자동/수동으로 새 브랜치 생성
│ "auto/design-tokens"
│ │
│ │ 여기서 코드 변경
│ │ tokens.json 수정
│ │ tokens.css 재생성
│ │
│ "Pull Request 생성"
│ ┌─────────────────────────────┐
│ │ 제목: 🎨 디자인 토큰 업데이트│
│ │ │
│ │ 변경 내용 (diff): │
│ │ - --color-primary-500: │
│ │ #3B82F6 → #2563EB │
│ │ │
│ │ [승인 ✅] [수정 요청 ❌] │
│ └─────────────────────────────┘
│ │
│ │ 개발자/리드가 검토 후 승인
│ │
└── main 브랜치에 Merge (합병)
PR이라고 부르는 이유
이름이 Pull Request인 이유가 약간 헷갈릴 수 있습니다.
Push (밀어넣기) = 내 코드를 원격 저장소로 올리는 것
Pull (당겨오기) = 원격 저장소 코드를 내 로컬로 가져오는 것
Pull Request =
"당신의 main 브랜치가 내 변경사항을 Pull(당겨)가도록
요청(Request)합니다"
→ 줄여서 PR
GitHub에서는 PR, GitLab에서는 MR(Merge Request) 라고 부르는데 같은 개념입니다.
PR이 중요한 이유 3가지
1. 코드 품질 보호
→ 아무나 main에 직접 푸시 불가
→ 반드시 검토 후 머지
2. 실수 방지
→ 토큰 값 하나 잘못 바뀌면
수백 개 컴포넌트 색상이 한번에 바뀜
→ PR에서 diff 확인 후 "이거 맞아?" 검토 가능
3. 히스토리 관리
→ 언제, 누가, 왜 바꿨는지 기록
→ 문제 생기면 이전 버전으로 되돌리기 가능
아까 파이프라인에서의 PR 위치
디자이너가 Figma에서 값 변경
↓
tokens.json 자동 커밋
↓
★ PR 자동 생성 ★ ← 봇이 자동으로 만들어줌
"토큰 업데이트 PR입니다"
↓
★ PR 리뷰 ★ ← 개발자가 diff 확인
변경된 토큰 2줄 확인
"맞네, 승인!"
↓
Merge (main에 합병)
↓
git pull → 로컬 동기화
결국 SSOT 파이프라인에서 PR은 "자동화된 변경사항이 실제 코드에 반영되기 전 마지막 안전망" 역할을 합니다. 완전 자동화도 가능하지만, 이 한 단계 검토를 두는 게 실무에서의 관행입니다 😊
1. Figma Variables — 무료 vs 유료
Figma Variables(변수) 기본 기능은 모든 요금제(무료 포함) 에서 생성·사용이 가능합니다. 단, 컬렉션당 생성할 수 있는 모드 수는 요금제에 따라 다릅니다.
실제 제한을 표로 보면 이렇습니다:
┌──────────────────────────────────────────────────────┐
│ 기능 무료(Starter) 유료(Pro+) │
├──────────────────────────────────────────────────────┤
│ Variables 생성·사용 ✅ ✅ │
│ 컬렉션당 모드 수 1개 4개+ │
│ 팀 라이브러리 게시 ❌ ✅ │
│ Dev Mode 변수 확인 ❌ ✅ │
│ GitHub 연동(Tokens Studio) △(제한적) ✅ │
└──────────────────────────────────────────────────────┘
실무적으로 중요한 포인트는 "모드(Mode)" 입니다. 모드가 1개라는 건 라이트/다크 테마 전환처럼 "같은 변수를 상황에 따라 다른 값으로" 쓰는 게 무료에서는 안 된다는 뜻입니다. SSOT 파이프라인을 제대로 구축하려면 에듀케이션, 프로페셔널, 오거니제이션, 엔터프라이즈 요금제가 필요합니다.
💡 학생이라면: Figma는 학교 이메일(.edu, .ac.kr 등)을 인증하면 Professional 플랜을 1년간 무료로 제공합니다.
2. Tailwind 없는 환경에서의 토큰 매핑
Tailwind는 토큰을 코드로 연결하는 방법 중 하나일 뿐입니다. Tailwind가 없어도 CSS Variables만으로 완벽하게 동작합니다.
Tailwind 사용 환경 Tailwind 미사용 환경
─────────────────────────────────────────────────────
tokens.json tokens.json
↓ ↓
tailwind.config.js에 매핑 tokens.css에 직접 변수 정의
↓ ↓
className="bg-primary-500" class="btn-primary"
(Tailwind 클래스로 사용) (CSS에서 변수 참조)
Tailwind가 없는 환경에서는 이렇게 사용합니다:
/* tokens.css — Style Dictionary가 자동 생성 */
:root {
--color-primary-500: #3B82F6;
--spacing-md: 16px;
--radius-button: 6px;
}
/* button.css — 토큰 변수를 직접 참조 */
.btn-primary {
background-color: var(--color-primary-500);
padding: var(--spacing-md);
border-radius: var(--radius-button);
}
<!-- HTML에서 사용 — Tailwind 클래스 없음 -->
<button class="btn-primary">클릭</button>
값이 바뀌어도 tokens.css 한 파일만 업데이트하면 .btn-primary를 쓰는 모든 곳이 자동으로 반영됩니다. Tailwind는 그 과정을 클래스 이름으로 편하게 쓰게 해주는 도구일 뿐이고, 핵심은 CSS Variables입니다.
3. 순수 HTML/CSS/JS 환경에서도 SSOT 체인 가능한가?
완전히 가능합니다! 오히려 순수 HTML/CSS/JS 환경이 SSOT 체인의 가장 기본 형태입니다.
Style Dictionary는 JSON 토큰을 CSS Variables, JS 모듈, SCSS 맵 등 다양한 형식으로 변환하며, 웹·iOS·Android 등 여러 플랫폼을 동시에 지원합니다. Tailwind 여부와 전혀 무관합니다.
파이프라인을 그리면 이렇습니다:
┌────────────────────────────────────────────────────────┐
│ Figma │
│ Variables 패널에서 색상 변경 │
└───────────────────────┬────────────────────────────────┘
│ Tokens Studio → Push to GitHub
▼
┌────────────────────────────────────────────────────────┐
│ tokens.json (GitHub) │
│ { "color": { "primary": { "value": "#2563EB" } } } │
└───────────────────────┬────────────────────────────────┘
│ GitHub Actions → Style Dictionary build
▼
┌────────────────────────────────────────────────────────┐
│ tokens.css (자동 생성) │
│ :root { │
│ --color-primary: #2563EB; ← 값 자동 반영 │
│ } │
└───────────────────────┬────────────────────────────────┘
│ PR 머지 → git pull
▼
┌────────────────────────────────────────────────────────┐
│ 순수 HTML/CSS/JS 프로젝트 │
│ │
│ .btn-primary { │
│ background: var(--color-primary); ← 자동 반영 ✅ │
│ } │
│ │
│ <button class="btn-primary">클릭</button> │
└────────────────────────────────────────────────────────┘
공공기관이나 레거시 환경처럼 프레임워크를 쓸 수 없는 곳에서도 이 구조로 디자이너-개발자 간 자동 동기화가 가능합니다. 실제로 현재 만들고 계신 UI 컴포넌트 가이드의 tokens.css가 이 파이프라인의 최종 산출물과 정확히 같은 구조입니다. 나중에 Figma 연동만 붙이면 SSOT 체인이 완성되는 거예요 😊
'Web.Dev' 카테고리의 다른 글
| 누구나 한 번쯤은 띄워본 JavaScript 에러 Top 10 (0) | 2022.05.09 |
|---|---|
| 깔끔한 console.log 출력 방법 (0) | 2022.02.08 |
| How to play audio? (0) | 2022.02.01 |
| <번역>자바스크립트 성능 향상 방법 (0) | 2022.01.26 |
| <번역>시니어 프론트엔드 개발자처럼 크롬 개발자도구 사용하기 (0) | 2022.01.26 |