Target ekspor default figmascope adalah Jetpack Compose. Namun bundel ini bersifat agnostik agen — jenis node IR, format token, dan string ref dipetakan sama bersihnya ke React + Tailwind. Anda hanya perlu memberi tahu agen untuk menarget JSX alih-alih Kotlin.

Panduan ini mencakup pemetaan IR-ke-JSX, cara memperluas tailwind.config.js dengan token dari tokens.json, dan pola prompting yang menghasilkan paling sedikit drift di sisi React.

Satu catatan penting terlebih dahulu

Compose adalah apa yang paling banyak diuji figmascope. IR, format token, dan batasan CONTEXT.md dirancang dengan mempertimbangkan Compose. React + Tailwind berfungsi — IR dipetakan dengan bersih — tetapi Anda akan melihat sedikit lebih banyak drift, terutama seputar tipografi dan layout overlay. Tandai apa pun yang terlihat salah dan jalankan pemeriksaan token setelah pass pertama.

Langkah 1: Buat dan ekstrak bundel

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

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

Langkah 2: Perluas konfigurasi Tailwind dengan design token

Sebelum melakukan prompting, petakan tokens.json ke dalam tailwind.config.js Anda. Ini adalah langkah kunci yang membuat Tailwind sadar token — alih-alih nilai hex hardcoded dalam string className, Anda mendapatkan nama semantik yang dapat ditelusuri kembali ke desain.

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

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

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

// Build border-radius map
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,
    }
  }
}

Ini menghasilkan kelas Tailwind seperti bg-brand-7f5cfe, p-ds-16, rounded-ds-12. Nama kelasnya tidak terlalu cantik, tetapi dapat ditelusuri — setiap kelas dipetakan kembali ke kunci token.

Jika Anda lebih suka memiliki alias semantik, tambahkan lapisan aliasing:

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

Berikan keduanya ke agen — konfigurasi token mentah dan alias semantik — sehingga ia dapat memilih nama yang tepat dalam konteks.

Langkah 3: Prompt agen untuk menarget React + Tailwind

CONTEXT.md mengatakan target default adalah Compose. Ganti secara eksplisit dalam prompt Anda:

Implement ./design/screens/home.json as a React functional component using Tailwind CSS.

Framework override: ignore the Compose instructions in CONTEXT.md. Target React + Tailwind.

Rules:
- Read ./design/tokens.json. The tokens are extended into Tailwind config —
  use Tailwind classes that correspond to token keys (e.g. bg-brand-7f5cfe, p-ds-16).
- UI strings come from ./design/strings.json. Import and reference them by key.
- IR node kind mapping:
    stack (axis:vertical)   → <div className="flex flex-col gap-[Xpx]">
    stack (axis:horizontal) → <div className="flex flex-row gap-[Xpx]">
    overlay                 → <div className="relative"> with absolute-positioned children
    absolute                → <div className="absolute" style={{top, left, width, height}}>
    leaf (text)             → <span> or <p> with Tailwind text classes
    leaf (rectangle)        → <div> with bg and rounded classes
- Do not hardcode hex values. All colors must use Tailwind classes from the token config.
- Do not hardcode strings. Use the strings.json keys.

Output to: src/screens/HomeScreen.tsx

Tabel pemetaan IR-ke-JSX

Berikut tabel pemetaan lengkap untuk React + Tailwind:

Jenis IRPropertiPola JSX
stackaxis: "vertical"<div className="flex flex-col gap-ds-{n}">
stackaxis: "horizontal"<div className="flex flex-row gap-ds-{n}">
overlaychildren berlapis<div className="relative"> dengan children 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}">

Nilai gap dan padding: gunakan kelas spacing ds-{n} dari ekstensi konfigurasi Tailwind. Jika nilai gap bukan kunci token yang bersih, gunakan sintaks nilai arbitrer Tailwind: gap-[20px].

Contoh nyata: IR home screen ke JSX

Menggunakan IR yang sama dari panduan Compose:

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>
  )
}

Setiap className dapat ditelusuri. gap-ds-24spacing.24 → 24px. text-brand-7f5cfecolor.7f5cfe#7F5CFE. Jika nilai drift (mis., agen menulis gap-6 alih-alih gap-ds-24), langsung terlihat dalam code review.

Mengapa tokens.json + konfigurasi Tailwind berfungsi

Kedua sistem berbasis token. Tailwind memperluas konfigurasi dasar dengan nilai kustom; tokens.json sudah terstruktur sebagai peta nilai kustom. Langkah ekstensi (Langkah 2 di atas) adalah pengaturan satu kali — setelah itu, agen menggunakan nama kelas Tailwind yang terikat secara semantik ke sistem desain daripada kelas utilitas arbitrer.

Hasilnya: ketika token desain berubah (misalnya, warna utama bergeser dari #7F5CFE ke #6B4EE6), Anda memperbarui satu nilai dalam tokens.json, menjalankan ulang impor konfigurasi, dan Tailwind meregenerasi. Kode komponen tidak berubah.

Pemeriksaan drift token

Setelah implementasi, minta agen untuk mengaudit drift:

Audit src/screens/HomeScreen.tsx for token drift.

Check:
1. Any hex color values not referenced through a Tailwind class from the token config.
2. Any hardcoded px or rem spacing values that should be ds-{n} classes.
3. Any UI strings not sourced from design/strings.json.

List violations. Produce a diff that fixes them.

Overlay dan absolute — kasus yang rumit

Node overlay membutuhkan parent relative dan children yang diposisikan absolute. IR mencantumkan children dalam urutan z (pertama = lapisan bawah). Beri tahu agen untuk mempertahankan urutan ini dalam JSX — React merender dalam urutan DOM dan CSS position: absolute menumpuk sesuai.

Node absolute menggunakan koordinat piksel mentah dari Figma. Ini hampir selalu berasal dari desain yang tidak dibangun dengan auto-layout. Jika Anda melihat banyak node absolute, biasanya berarti file Figma memiliki positioning manual — kode yang dihasilkan akan rapuh pada ukuran viewport yang berbeda. Pertimbangkan untuk menandai ini dan melakukan refactoring ke layout flex.

Penanganan string di React

Tidak seperti Android (di mana kunci strings.json dipetakan ke ID resource R.string.*), di React Anda mengimpor JSON secara langsung:

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

// penggunaan
{strings['home.title'].value}
// atau dengan fallback
{strings['home.title']?.value ?? strings['home.title']?.fallback ?? 'Untitled'}

Jika Anda menggunakan library i18n (react-i18next, next-intl), kunci notasi titik dalam strings.json dipetakan langsung ke namespace kunci terjemahan. Beri tahu agen library i18n mana yang Anda gunakan sehingga ia menghasilkan pola panggilan yang tepat.

Keterbatasan jujur di sisi React

Utilitas tipografi. Utilitas teks Tailwind (text-xs, text-2xl) tidak dipetakan 1:1 ke token typography dalam tokens.json. Tailwind memiliki skala tipe tetap; file token memiliki ukuran arbitrer. Anda perlu memperluas konfigurasi fontSize Tailwind dengan nilai token atau menggunakan nilai arbitrer (text-[24px]). Keduanya berfungsi; memperluas konfigurasi lebih bersih.

Line height. Masalah yang sama — utilitas leading Tailwind tidak cocok dengan nilai lineHeight arbitrer. Gunakan leading-[{value}] atau perluas konfigurasi.

Gradien. Tidak didukung dalam IR. Fill gradien apa pun muncul sebagai peringatan dalam _meta.json dan dihilangkan dari properti fill node. Tangani secara manual.

Tidak satu pun dari ini yang merupakan pemblokir — ini adalah keterbatasan yang diketahui. Fondasi yang sadar token sudah solid; tepiannya hanya perlu penanganan manual.

Mulai dengan figmascope untuk mengekspor bundel Anda, kemudian gunakan panduan ini bersama alur kerja Cursor atau alur kerja Claude Code untuk mengarahkan implementasi.