O alvo de export padrão do figmascope é Jetpack Compose. Mas o bundle é agnóstico de agente — os tipos de nó do IR, o formato de tokens e as string refs mapeiam com a mesma clareza para React + Tailwind. Você simplesmente diz ao agente para visar JSX em vez de Kotlin.
Este guia cobre o mapeamento IR-para-JSX, como estender tailwind.config.js com tokens de tokens.json, e os padrões de prompt que produzem o menor desvio no lado React.
Uma ressalva importante logo de início
Compose é o que o figmascope testa mais. O IR, o formato de tokens e as restrições do CONTEXT.md foram projetados com Compose em mente. React + Tailwind funciona — o IR mapeia claramente — mas você verá um pouco mais de desvio, especialmente em torno de tipografia e layouts overlay. Sinalize qualquer coisa que pareça errada e faça uma verificação de tokens após o primeiro passo.
Passo 1: Gere e descompacte o bundle
unzip ~/Downloads/context-bundle.zip -d ./design/
ls design/
# CONTEXT.md _meta.json components/ screens/ strings.json tokens.json
Passo 2: Estenda a configuração Tailwind com design tokens
Antes de fazer o prompt, mapeie tokens.json no seu tailwind.config.js. Este é o passo fundamental que torna o Tailwind ciente de tokens — em vez de valores hex hardcoded em strings de className, você obtém nomes semânticos que rastreiam de volta ao design.
// tailwind.config.js
const tokens = require('./design/tokens.json')
// Cria mapa de cores: { 'brand-7f5cfe': '#7F5CFE', ... }
const colors = Object.fromEntries(
Object.entries(tokens.color).map(([key, val]) => [
`brand-${key}`, val
])
)
// Cria mapa de espaçamento: { 'ds-4': '4px', 'ds-8': '8px', ... }
const spacing = Object.fromEntries(
Object.entries(tokens.spacing).map(([key, val]) => [
`ds-${key}`, `${val}px`
])
)
// Cria mapa de border-radius
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,
}
}
}
Isso produz classes Tailwind como bg-brand-7f5cfe, p-ds-16, rounded-ds-12. Não são os nomes de classe mais bonitos, mas são rastreáveis — cada classe mapeia de volta para uma chave de token.
Se preferir aliases semânticos, adicione uma camada de alias:
// em theme.extend.colors:
primary: tokens.color['7f5cfe'],
background: tokens.color['f6f2ea'],
surface: tokens.color['ffffff'],
Dê ao agente os dois — a configuração de token bruta e os aliases semânticos — para que ele possa escolher o nome certo no contexto.
Passo 3: Faça o prompt para o agente visar React + Tailwind
O CONTEXT.md diz que o alvo padrão é Compose. Substitua explicitamente no seu prompt:
Implemente ./design/screens/home.json como um componente funcional React usando Tailwind CSS.
Substituição de framework: ignore as instruções de Compose no CONTEXT.md. Vise React + Tailwind.
Regras:
- Leia ./design/tokens.json. Os tokens são estendidos na configuração Tailwind —
use classes Tailwind que correspondam a chaves de token (ex.: bg-brand-7f5cfe, p-ds-16).
- Strings de UI vêm de ./design/strings.json. Importe e referencie-as pela chave.
- Mapeamento de tipo de nó 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"> com filhos posicionados absolutamente
absolute → <div className="absolute" style={{"{{"}}top, left, width, height{{"}}"}}>
leaf (text) → <span> ou <p> com classes de texto Tailwind
leaf (rectangle) → <div> com classes bg e rounded
- Não hardcode valores hex. Todas as cores devem usar classes Tailwind da config de tokens.
- Não hardcode strings. Use as chaves de strings.json.
Saída para: src/screens/HomeScreen.tsx
O mapeamento IR-para-JSX
Aqui está a tabela de mapeamento completa para React + Tailwind:
| Tipo IR | Propriedades | Padrão JSX |
|---|---|---|
stack | axis: "vertical" | <div className="flex flex-col gap-ds-{n}"> |
stack | axis: "horizontal" | <div className="flex flex-row gap-ds-{n}"> |
overlay | filhos em camadas | <div className="relative"> com filhos className="absolute ..." |
absolute | x, y, w, h | <div className="absolute" style={{"{{"}}top: y, left: x, width: w, height: h{{"}}"}}> |
leaf | type: "text" | <span className="text-{size} font-{weight} leading-{lh} text-brand-{color}"> |
leaf | type: "rectangle" | <div className="bg-brand-{color} rounded-ds-{r}"> |
Valores de gap e padding: use as classes de espaçamento ds-{n} da extensão de configuração Tailwind. Se o valor de gap não for uma chave de token limpa, use a sintaxe de valor arbitrário do Tailwind: gap-[20px].
Um exemplo real: IR da tela home para JSX
Usando o mesmo IR do passo a passo do 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>
)
}
Cada className é rastreável. gap-ds-24 → spacing.24 → 24px. text-brand-7f5cfe → color.7f5cfe → #7F5CFE. Se um valor desviar (ex.: o agente escrever gap-6 em vez de gap-ds-24), fica visível imediatamente numa revisão de código.
Por que tokens.json + config Tailwind funciona
Ambos os sistemas são token-first. O Tailwind estende uma configuração base com valores customizados; tokens.json já está estruturado como um mapa de valores customizados. A etapa de extensão (Passo 2 acima) é uma configuração única — depois disso, o agente usa nomes de classe Tailwind que estão semanticamente vinculados ao design system em vez de classes utilitárias arbitrárias.
O resultado: quando o token de design muda (digamos, a cor primária passa de #7F5CFE para #6B4EE6), você atualiza um valor em tokens.json, re-roda o import da config, e o Tailwind regenera. O código do componente não muda.
Verificação de desvio de tokens
Após a implementação, peça ao agente para auditar o desvio:
Audite src/screens/HomeScreen.tsx para desvio de tokens.
Verifique:
1. Quaisquer valores de cor hex não referenciados por uma classe Tailwind da config de tokens.
2. Quaisquer valores px ou rem hardcoded de espaçamento que deveriam ser classes ds-{n}.
3. Quaisquer strings de UI não originadas de design/strings.json.
Liste violações. Produza um diff que as corrija.
Overlay e absolute — os casos difíceis
Nós overlay precisam de um pai relative e filhos posicionados absolute. O IR lista filhos em ordem z (primeiro = camada inferior). Diga ao agente para preservar essa ordem no JSX — o React renderiza em ordem DOM e o CSS position: absolute empilha de acordo.
Nós absolute usam coordenadas de pixel brutas do Figma. Quase sempre vêm de designs que não foram construídos com auto-layout. Se você está vendo muitos nós absolute, geralmente significa que o arquivo Figma tem posicionamento manual — o código gerado será frágil em diferentes tamanhos de viewport. Considere sinalizar isso e refatorar para layouts flex.
Tratamento de strings no React
Ao contrário do Android (onde as chaves de strings.json mapeiam para IDs de recurso R.string.*), no React você importa o JSON diretamente:
import strings from '../../design/strings.json'
// uso
{strings['home.title'].value}
// ou com fallback
{strings['home.title']?.value ?? strings['home.title']?.fallback ?? 'Sem título'}
Se você está usando bibliotecas i18n (react-i18next, next-intl), as chaves em notação de ponto em strings.json mapeiam diretamente para namespaces de chave de tradução. Diga ao agente qual biblioteca i18n você está usando para que ele gere o padrão de chamada correto.
Lacunas honestas no lado React
Utilitários de tipografia. Os utilitários de texto do Tailwind (text-xs, text-2xl) não mapeiam 1:1 para os tokens typography em tokens.json. O Tailwind tem uma escala de tipo fixa; o arquivo de tokens tem tamanhos arbitrários. Você precisará either estender a config fontSize do Tailwind com valores de token ou usar valores arbitrários (text-[24px]). Ambos funcionam; estender a config é mais limpo.
Line height. Mesmo problema — os utilitários leading do Tailwind não correspondem a valores de lineHeight arbitrários. Use leading-[{value}] ou estenda a config.
Gradientes. Não suportados no IR. Qualquer fill com gradiente aparece como aviso em _meta.json e é omitido da propriedade fill do nó. Trate manualmente.
Nenhuma dessas lacunas é bloqueante — são lacunas conhecidas. A fundação ciente de tokens é sólida; as bordas precisam apenas de tratamento manual.
Comece com o figmascope para exportar seu bundle, depois use este guia junto com o fluxo Cursor ou o fluxo Claude Code para conduzir a implementação.