디자이너가 토큰을 바꾸면 슬랙으로 전달받아 손으로 옮겨 적었고, 빠뜨린 건 QA에서 발견됐습니다.
"이걸 왜 사람이 하지?"가 시작이었습니다.
Figma를 SSOT로 두는 파이프라인을 만들고,
그 위에 신규 디자인 시스템을 구축해 전사 웹 프로덕트에 적용 중입니다.
자비스앤빌런즈(삼쩜삼) · FE 3인 팀 · 파이프라인 설계·구현 주도 (기여도 80%) · 디자이너와 토큰 컨벤션 공동 정의
⚠ 어디까지 반영됐는지 아무도 모름
$ pnpm figma:pull && pnpm build ✓ 571 tokens → CSS / Tailwind ✓ validator 571/571
누락이 있으면 QA가 아니라 빌드가 알려줍니다
surface-primarysurface-primary가 Figma 변수 → JSON → CSS 변수 → 컴포넌트까지 네 계층을 그대로 관통합니다.Variables(토큰 컬렉션 4계층) + ComponentSet(컴포넌트 정의)
surface-primary
LightDark
:root { --surface-primary: #15b077 }
.dark { --surface-primary: #0e8a5f }
CSS 변수 571개 ×2 모드 + Tailwind v4 @theme 출력.
누락은 validator가 빌드 실패로 차단
variant=primary · size=large
"variant=primary, size=large, …": {
"base": { "fill": "$surface-primary" }
}
variant·슬롯별 스타일을 담은 스펙 JSON 65종, 구현의 단일 참조점
<Button variant="primary" size="large">
시안을 raw CSS/div로 다시 만들지 않도록, 사람에게도 AI에게도 실제 컴포넌트 코드를 바로 제공
버튼 색은 #15b077 같은 값이 아니라 "시맨틱 토큰을 따라간다"로 저장돼 있습니다 (var() 참조).
시맨틱 토큰 54개만 갈아끼우면 그걸 따라가는 모든 컴포넌트가 함께 바뀝니다.
/* 빌드 산출물 — 컴포넌트 토큰은 참조를 보존한다 */ :root { --surface-primary: #15b077; } [data-theme="brand-b"] { --surface-primary: #d97a06; } /* 시맨틱 54개만 오버라이드 */ --primary-enabled-button-surface: var(--surface-primary); /* hex로 굳히지 않음 → 브랜드가 바뀌면 따라감 */
버튼 하나의 상태 조합이 120개(variant 5 × 형태 2 × 크기 4 × 상태 3)입니다.
이걸 하나씩 클릭해 옮겨 적는 게 구현에서 가장 오래 걸리는 일이었습니다.
// After — 명령 한 번으로 생성되는 spec.json "size=small, state=enabled, value=selected": { "switch-track": { "fill": "$surface-primary", "cornerRadius": 999 }, "switch-thumb": { "fill": "$icon-basic-inverse" } }
디자인이 바뀌면 spec.json의 diff로 드러나서 디자인 변경도 코드처럼 리뷰됩니다. 코드 생성까지는 자동화하지 않았습니다. 인터페이스와 접근성은 스펙만으로 판단할 수 없어 사람이 결정합니다.
$ pnpm figma:sync 발견된 spec.json 파일: 65개 571개의 디자인 토큰 로드 완료 🔄 Button/spec.json 동기화 중... ⏭ 변경사항 없음 🔄 Switch/spec.json 동기화 중... ✅ 완료 (스타일 2건 갱신) 🔄 Input/spec.json 동기화 중... ⏭ 변경사항 없음 … 62개 생략 … 동기화 완료: 1개 갱신, 64개 변경 없음, 0개 실패
"잘 지켜달라"는 부탁 대신, 디자인과 코드가 서서히 어긋나는 드리프트를 각 단계의 검증이 빌드 실패로 막습니다.
$ pnpm build ✗ css-validator — missing token: surface-tertiary (570/571) build failed
| 게이트 | 지키는 것 | 어기면 |
|---|---|---|
| 토큰 validator | 소스 토큰 ↔ 생성된 CSS 변수 1:1 (571개 전수 대조) | 빌드 실패 |
| 참조 치환 검사 | 깨진 토큰 참조가 CSS로 새어 나가 조용히 무효화되는 것 | 빌드 실패 |
| Code Connect 검사기 | Figma 속성 rename·옵션 변경으로 51종 매핑이 어긋나는 것 | exit 1 |
| 스킬 문서 검증 | 가이드 예제 코드를 실제 컴포넌트 타입으로 컴파일 | 머지 전 검사 실패 |
Dev Mode에서 시안을 클릭했을 때 보이는 코드를 바꿉니다.
display: flex; padding: 13px 20px; background: #15b077; border-radius: 12px; …
CSS 덩어리를 보고 raw CSS로 재구현 → 시스템 우회
<Button variant="primary" size="large"> 환급액 조회하기 </Button>
이 코드를 그대로 복사해 쓰면 됩니다
컴포넌트 prop이 바뀌어 매핑이 어긋나면 push 단계에서 막습니다
사용 가이드 35편을 스킬로 배포해, AI가 raw div 대신 시스템 컴포넌트로 구현하게 합니다.
<Button variant="primary" size="large">
가이드의 예제 코드는 머지 전에 실제 컴포넌트 타입으로 컴파일해 검증합니다
2026년 7월 사내 공개 후 6주 만에, 전사 웹 앱 18개 중 8개가 실사용 중입니다.
앱별 시스템 컴포넌트 import 파일 수 (2026-09 기준)