Figma를 단일 진실 원천으로 활용해 5주 만에 60개 이상의 디자인 시스템 컴포넌트를 출시한 방법

발행: (2026년 5월 27일 AM 08:26 GMT+9)
12 분 소요
원문: Dev.to

출처: Dev.to

개요

우리는 300 엔지니어‑일을 예상했습니다. 실제로는 35일 안에 3,077개의 테스트원시 HEX 값 제로로 배포했습니다. 아래는 Figma를 코드베이스의 문자 그대로 진리의 원천으로 만들기 위해 제가 구축한 파이프라인입니다.

모든 프론트‑엔드 개발자는 그 고통을 잘 알고 있습니다.

  1. 디자이너가 Figma 파일을 내려줍니다. 픽셀 단위로 완벽하고 모든 인터랙션 상태를 포함합니다.
  2. 에디터를 열고 변환 프로세스를 시작합니다.

두 화면을 번갈아 보게 됩니다:

  • “그 회색 색상은 뭐지?”
  • “8 px와 12 px 중 어느 것이 맞지?”
  • “이 폰트의 굵기는? MD_Medium, MD_SemiBold?”

질문은 짧지만 답은 매우 중요합니다. Figma 파일과 멀어질수록 컴포넌트는 원래 아이디어에서 점점 벗어나게 됩니다.

이것은 부주의의 결과가 아니라 구조적인 문제입니다. Figma와 코드는 같은 진실을 표현하는 두 가지 매우 다른 방식이며, 새로운 엔지니어가 눈으로 사양을 다시 해석할 때마다 편차가 발생합니다.


실제 수치로 본 비용

우리 디자인 시스템에는 60개가 넘는 컴포넌트를 구현해야 했습니다. 노력 추정치는 보수적으로 컴포넌트당 4–5 엔지니어‑일이었습니다.

그 결과 디자인 편차를 포함해 약 300 엔지니어‑일이 소요되었습니다.

전형적인 실패 패턴

일차활동
1엔지니어가 Figma 사양을 읽고 토큰 이름을 추측
2‑3컴포넌트를 손수 작성
3QA 피드백 – 색상이나 간격이 잘못됨
4수정 및 리뷰
5테스트(시간이 허락한다면)

일주일이 지나면 컴포넌트는 계속해서 편차가 쌓입니다. 진리의 원천은 엔지니어에게 프로그래밍되지 않은 Figma 파일이었고, 단지 눈으로 보는 것이 전부였습니다.


Figment를 만들었는가

통찰은 간단했습니다: 엔지니어가 Figma 파일을 읽는 것이 나쁜 것이 아니라, 모든 파일을 다 읽어야 했다는 점이 문제였습니다.

만약 Figma가 인간의 오류가 끼어들 가능성이 있는 레이어 없이 직접 코드베이스와 대화할 수 있다면 어떨까요?

그것이 Figment가 탄생한 배경입니다.

목표는 인간의 판단을 빼앗는 것이 아니라 디자이너가 여전히 계층 구조, 의도, 강조를 결정하도록 하는 것이었습니다. 하지만 번역의 기계적인 측면—정확한 HEX 값, 정밀한 간격, 폰트‑변형 매핑—은 이미 Figma 파일에 존재합니다.

60개의 컴포넌트 중 50번째를 반복해서 같은 60개의 질문에 답하는 것은 인간에게 의미가 없었습니다.


초기 제한 사항 중 하나

생성된 모든 컴포넌트는 다음을 사용해야 했습니다:

  • 시맨틱 디자인 토큰(원시 HEX 값 금지)
  • MUI sx props(외부 스타일시트 금지)
  • TypeScript strict mode
  • 의미 있는 Figma 변형마다 Storybook 스토리
  • CI에서 편차를 잡아내는 Spec‑lock 테스트

Figment는 엔지니어가 정리할 수 있는 거친 시작점을 제공하기 위해 만든 것이 아닙니다.
동일한 날에 리뷰하고 바로 배포할 수 있는 코드를 생성하기 위해 만든 것입니다.


Figment 작동 방식: 3단계 파이프라인

단계 1 – 토큰 정찰

컴포넌트가 사용하는 디자인 토큰은 이미 코드베이스에 존재해야 합니다. 단계 1은 다음을 수행합니다:

  1. 대상 노드의 Figma fill을 가져옵니다.
  2. 기존 토큰 파일과 비교합니다.
  3. 누락된 토큰을 추가하기 위한 패치를 출력합니다(토큰 파일에 붙여넣을 수 있음).

Figma API 호출 1회. 약 30 초. 애매함의 여지가 없습니다.

단계 2 – 토큰 저작(인간 개입)

엔지니어는 제안된 토큰 추가를 검토하고 적절한 시맨틱 그룹에 배치합니다. 디자인 의도는 자동화만으로 완전히 포착할 수 없기 때문에 이 수동 단계가 필요합니다.

예시: 시스템 상태는 surface.pressed라는 색상으로 표시됩니다; 원시 HEX 값만으로는 의미를 전달할 수 없습니다.

단계 3 – 결정적 컴포넌트 생성

Figment는 스크린샷으로부터 컴포넌트를 만드는 AI와 다릅니다. 정확히 결정될 수 있는 모든 값은 AI 모델에 데이터가 전달되기 전에 고정됩니다:

  • 타이포그래피 – 알고리즘으로 해결(예: 12 px + weight 500 = MD_Medium, line‑height 16 px). 제안이 아니라 사실로 주입.
  • 간격 및 아이콘 크기 – Figma의 바운딩‑박스 데이터에서 직접 가져옴(소수점까지 정확, 반올림 없음).
  • 변형 커버리지 – 모든 변형 차원을 파싱하면 필수 커버리지 블록을 추가; 그렇지 않으면 추론.

생성 후 검증(디스크에 쓰기 전 스캔):

금지 패턴처리
원시 HEX 값거부
다른 수정자 없이 숫자형 border‑radius(예: blur, drop‑shadow)허용하지만 4배(MUI) 적용
토큰 import 누락거부
잘못된 focus‑ring shadow 순서거부

파일은 모든 검사를 통과한 경우에만 기록됩니다—조용히 실패하지 않습니다.


단일 실행이 만들어내는 결과

Figment는 컴포넌트당 3개의 파일을 생성합니다(스캐폴드가 아니라 완전한 리뷰‑가능 PR 패키지):

  1. 컴포넌트 파일 – 시맨틱 토큰, MUI sx props, TypeScript strict mode 포함.
  2. Storybook 스토리 – 의미 있는 Figma 변형마다 하나씩.
  3. Spec‑lock 테스트 – CI 검사용 토큰 및 간격 값 전체 저장.

세 아티팩트는 동시에 생성·검증·출력됩니다. 엔지니어는 단지 정확성을 확인하면 되며, 다시 작성할 필요가 없습니다.


의도적인 Figma와의 차이점 처리

모든 사양을 그대로 복사해야 하는 것은 아닙니다. 경우에 따라:

  • 디자이너가 자식 컴포넌트에 적용되는 타이포그래피를 정의한다.
  • 간격 값이 레이아웃 프레임의 산출물일 뿐, 컴포넌트 자체 규칙이 아니다.

Figment는 각 컴포넌트와 함께 위치한 figment.overrides.json 파일을 통해 이를 관리합니다. Figma와 의도적으로 차이가 나는 모든 경우는 이유와 함께 문서화됩니다—숨겨진 예외는 없습니다.

{
  "overrides": {
    "componentName": {
      "tokenName": {
        "value": "#123456",
        "reason": "디자인 시스템에서 정확한 Figma 색상 대신 브랜드 색상을 사용"
      },
      "spacing": {
        "value": "8px",
        "reason": "모바일에서 시각적 균형을 맞추기 위해 조정"
      }
    }
  }
}

TL;DR

  • Figment는 Figma를 직접 생산‑준비 코드로 연결하는 진리의 원천으로 전환합니다.
  • 토큰 탐색을 없애고 디자인 편차를 줄이며 수 주간의 엔지니어링 작업을 절감합니다.
  • 파이프라인은 결정적이며 완전 검증된 후, 한 번의 실행으로 컴포넌트, Storybook 스토리, Spec‑lock 테스트를 생성합니다.

결과: 300 엔지니어‑일을 절감하고 35 일에 배포, 3,077개의 테스트와 원시 HEX 값 제로를 달성했습니다.

verify-figma로 CI에서 자동 편차 감지

올바른 컴포넌트를 만드는 것은 한 문제일 뿐입니다. 코드베이스가 진화하면서 올바름을 유지하는 것은 별개의 문제입니다.

미래 엔지니어가 토큰 이름을 바꾸거나, Figma 확인 없이 간격 값을 조정하거나, 급하게 색을 교체하면 디자인 시스템은 조용히 부패합니다.

Figment는 verify-figma라는 스크립트로 이를 해결합니다. 이 스크립트는 모든 Pull Request에서 실행됩니다:

npm run verify-figma -- --component Badge --live --figma-node 397:23320

Typography      12px / weight 500  variant="MD_Medium"  PASS
Spacing         gap in "Icon + Label"  6px              PASS
Colors          raw hex  No raw hex values               PASS
Border‑radius   6 checks  PASS | 6 passed, 0 warnings, 0 errors

0 조회
Back to Blog

관련 글

더 보기 »