figmascope의 기본 내보내기 대상은 Jetpack Compose입니다. 하지만 번들은 에이전트 독립적입니다 — IR 노드 종류, 토큰 형식, 문자열 참조는 React + Tailwind에도 동일하게 깔끔하게 매핑됩니다. 그냥 에이전트에게 Kotlin 대신 JSX를 대상으로 하라고 하면 됩니다.

이 가이드는 IR-to-JSX 매핑, tokens.json의 토큰으로 tailwind.config.js를 확장하는 방법, 그리고 React 사이드에서 드리프트가 가장 적은 프롬프팅 패턴을 다룹니다.

처음에 중요한 주의 사항

Compose는 figmascope가 가장 많이 테스트하는 것입니다. IR, 토큰 형식, CONTEXT.md 제약은 Compose를 염두에 두고 설계되었습니다. React + Tailwind는 작동합니다 — IR이 깔끔하게 매핑됩니다 — 하지만 특히 typography와 overlay 레이아웃 주변에서 약간 더 많은 드리프트가 발생합니다. 이상해 보이는 것을 표시하고 첫 번째 패스 후에 토큰 체크를 실행하세요.

1단계: 번들 생성 및 압축 해제

unzip ~/Downloads/context-bundle.zip -d ./design/

ls design/
# CONTEXT.md  _meta.json  components/  screens/  strings.json  tokens.json

2단계: 디자인 토큰으로 Tailwind 구성 확장

프롬프팅 전에 tokens.jsontailwind.config.js에 매핑하세요. 이것이 Tailwind를 토큰 인식하게 만드는 핵심 단계입니다 — className 문자열의 하드코딩된 16진수 값 대신, 디자인으로 추적할 수 있는 의미론적 이름을 얻습니다.

// tailwind.config.js
const tokens = require('./design/tokens.json')

// 색상 맵 구성: { 'brand-7f5cfe': '#7F5CFE', ... }
const colors = Object.fromEntries(
  Object.entries(tokens.color).map(([key, val]) => [
    `brand-${key}`, val
  ])
)

// 간격 맵 구성: { 'ds-4': '4px', 'ds-8': '8px', ... }
const spacing = Object.fromEntries(
  Object.entries(tokens.spacing).map(([key, val]) => [
    `ds-${key}`, `${val}px`
  ])
)

// 테두리 반경 맵 구성
const borderRadius = Object.fromEntries(
  Object.entries(tokens.radius).map(([key, val]) => [
    `ds-${key}`, val === 9999 ? '9999px' : `${val}px`
  ])
)

module.exports = {
  content: ['./src/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {
      colors,
      spacing,
      borderRadius,
    }
  }
}

이것은 bg-brand-7f5cfe, p-ds-16, rounded-ds-12와 같은 Tailwind 클래스를 생성합니다. 가장 예쁜 클래스 이름은 아니지만 추적 가능합니다 — 모든 클래스가 토큰 키로 매핑됩니다.

의미론적 별칭을 원한다면 별칭 레이어를 추가하세요:

// theme.extend.colors에서:
primary: tokens.color['7f5cfe'],
background: tokens.color['f6f2ea'],
surface: tokens.color['ffffff'],

에이전트에게 두 가지 모두를 제공하세요 — 원시 토큰 구성과 의미론적 별칭 — 그러면 컨텍스트에서 올바른 이름을 선택할 수 있습니다.

3단계: React + Tailwind를 대상으로 에이전트에게 프롬프팅

CONTEXT.md는 기본 대상이 Compose라고 말합니다. 프롬프트에서 명시적으로 재정의하세요:

./design/screens/home.json을 Tailwind CSS를 사용하는 React 함수형 컴포넌트로 구현하세요.

프레임워크 재정의: CONTEXT.md의 Compose 지시사항을 무시하세요. React + Tailwind를 대상으로 합니다.

규칙:
- ./design/tokens.json을 읽으세요. 토큰은 Tailwind 구성으로 확장됩니다 —
  토큰 키에 해당하는 Tailwind 클래스를 사용하세요 (예: bg-brand-7f5cfe, p-ds-16).
- UI 문자열은 ./design/strings.json에서 옵니다. 가져와서 키로 참조하세요.
- IR 노드 종류 매핑:
    stack (axis:vertical)   → <div className="flex flex-col gap-[Xpx]">
    stack (axis:horizontal) → <div className="flex flex-row gap-[Xpx]">
    overlay                 → <div className="relative"> 절대 위치 자식 포함
    absolute                → <div className="absolute" style={{"{{"}}top, left, width, height{{"}}"}}>
    leaf (text)             → <span> 또는 <p> Tailwind 텍스트 클래스 포함
    leaf (rectangle)        → <div> bg와 rounded 클래스 포함
- 16진수 값을 하드코딩하지 마세요. 모든 색상은 토큰 구성의 Tailwind 클래스를 사용해야 합니다.
- 문자열을 하드코딩하지 마세요. strings.json 키를 사용하세요.

출력: src/screens/HomeScreen.tsx

IR-to-JSX 매핑

React + Tailwind를 위한 전체 매핑 표:

IR 종류속성JSX 패턴
stackaxis: "vertical"<div className="flex flex-col gap-ds-{n}">
stackaxis: "horizontal"<div className="flex flex-row gap-ds-{n}">
overlay레이어드 자식<div className="relative">className="absolute ..." 자식
absolutex, y, w, h<div className="absolute" style={{"{{"}}top: y, left: x, width: w, height: h{{"}}"}}>
leaftype: "text"<span className="text-{size} font-{weight} leading-{lh} text-brand-{color}">
leaftype: "rectangle"<div className="bg-brand-{color} rounded-ds-{r}">

간격과 패딩 값: Tailwind 구성 확장의 ds-{n} 간격 클래스를 사용하세요. 간격 값이 깔끔한 토큰 키가 아닌 경우, Tailwind의 임의 값 구문을 사용하세요: gap-[20px].

실제 예시: 홈 화면 IR에서 JSX로

Compose 가이드의 동일한 IR 사용:

import strings from '../../design/strings.json'

export function HomeScreen() {
  return (
    <div className="flex flex-col gap-ds-24 p-ds-16 bg-brand-f6f2ea min-h-screen">
      <h1 className="text-2xl font-bold leading-tight text-brand-1a1a2e">
        {strings['home.title'].value}
      </h1>
      <div className="flex flex-col gap-ds-12">
        <div className="bg-white rounded-ds-12 p-ds-16">
          <span className="text-xs font-medium text-brand-7f5cfe">
            {strings['home.card.label'].value}
          </span>
        </div>
      </div>
    </div>
  )
}

모든 className이 추적 가능합니다. gap-ds-24spacing.24 → 24px. text-brand-7f5cfecolor.7f5cfe#7F5CFE. 값이 드리프트하면 (예: 에이전트가 gap-ds-24 대신 gap-6을 쓰면), 코드 리뷰에서 즉시 보입니다.

tokens.json + Tailwind 구성이 작동하는 이유

두 시스템 모두 토큰 우선입니다. Tailwind는 커스텀 값으로 기본 구성을 확장합니다; tokens.json은 이미 커스텀 값 맵으로 구조화되어 있습니다. 확장 단계(위의 2단계)는 일회성 설정입니다 — 그 후에 에이전트는 임의의 유틸리티 클래스가 아닌 디자인 시스템에 의미론적으로 연결된 Tailwind 클래스 이름을 사용합니다.

결과: 디자인 토큰이 변경될 때 (예: 기본 색상이 #7F5CFE에서 #6B4EE6으로 변경), tokens.json에서 하나의 값을 업데이트하고, 구성 가져오기를 재실행하면, Tailwind가 재생성됩니다. 컴포넌트 코드는 변경되지 않습니다.

토큰 드리프트 체크

구현 후, 에이전트에게 드리프트를 감사하도록 요청하세요:

src/screens/HomeScreen.tsx에서 토큰 드리프트를 감사하세요.

확인:
1. 토큰 구성의 Tailwind 클래스를 통해 참조되지 않은 모든 16진수 색상 값.
2. ds-{n} 클래스여야 하는 하드코딩된 px 또는 rem 간격 값.
3. design/strings.json에서 소싱되지 않은 모든 UI 문자열.

위반 사항을 나열하세요. 수정하는 diff를 생성하세요.

Overlay와 absolute — 까다로운 경우

Overlay 노드relative 부모와 absolute 위치 자식이 필요합니다. IR은 자식들을 z-순서로 나열합니다 (첫 번째 = 아래 레이어). 에이전트에게 JSX에서 이 순서를 보존하도록 지시하세요 — React는 DOM 순서로 렌더링하고 CSS position: absolute는 그에 따라 쌓입니다.

Absolute 노드는 Figma의 원시 픽셀 좌표를 사용합니다. 이것은 거의 항상 auto-layout 없이 만들어진 디자인에서 옵니다. 많은 absolute 노드가 보인다면 Figma 파일이 수동 위치 지정을 가지고 있다는 것을 의미합니다 — 생성된 코드는 다른 뷰포트 크기에서 취약할 것입니다. 이것을 표시하고 flex 레이아웃으로 리팩터링하는 것을 고려하세요.

React에서의 문자열 처리

Android(strings.json 키가 R.string.* 리소스 ID에 매핑됨)와 달리, React에서는 JSON을 직접 가져옵니다:

import strings from '../../design/strings.json'

// 사용법
{strings['home.title'].value}
// 또는 폴백과 함께
{strings['home.title']?.value ?? strings['home.title']?.fallback ?? 'Untitled'}

i18n 라이브러리(react-i18next, next-intl)를 사용하는 경우, strings.json의 점 표기법 키가 번역 키 네임스페이스에 직접 매핑됩니다. 에이전트에게 어떤 i18n 라이브러리를 사용하는지 알려주면 올바른 호출 패턴을 생성합니다.

React 사이드의 솔직한 한계

Typography 유틸리티. Tailwind의 텍스트 유틸리티(text-xs, text-2xl)는 tokens.jsontypography 토큰에 1:1로 매핑되지 않습니다. Tailwind는 고정된 타입 스케일을 가집니다; 토큰 파일은 임의의 크기를 가집니다. Tailwind의 fontSize 구성을 토큰 값으로 확장하거나 임의 값(text-[24px])을 사용해야 합니다. 두 가지 모두 작동합니다; 구성을 확장하는 것이 더 깔끔합니다.

줄 높이. 동일한 문제 — Tailwind의 leading 유틸리티는 임의의 lineHeight 값과 일치하지 않습니다. leading-[{value}]를 사용하거나 구성을 확장하세요.

그라디언트. IR에서 지원되지 않습니다. 모든 그라디언트 fill은 _meta.json의 경고로 나타나고 노드의 fill 속성에서 생략됩니다. 수동으로 처리하세요.

이것들 중 어느 것도 차단은 아닙니다 — 알려진 한계입니다. 토큰 인식 기반은 견고합니다; 엣지만 수동 처리가 필요합니다.

figmascope로 시작하여 번들을 내보내고, Cursor 워크플로Claude Code 워크플로와 함께 이 가이드를 사용하여 구현을 진행하세요.