@kylebrodeur/code-to-figma
v0.1.4
Published
CLI tool for syncing React components to Figma designs
Maintainers
Readme
@kylebrodeur/code-to-figma
CLI for parsing React components and generating Figma-compatible JSON.
Install
npm install -g @kylebrodeur/code-to-figma
# or
npx @kylebrodeur/code-to-figma <command>Requires Node.js 18+.
Commands
init
Create a .code-to-figma.json config file in the current directory.
code-to-figma init
code-to-figma init --force # overwrite existingOutput: .code-to-figma.json
scan <filePattern>
Parse React component(s) and generate .figma.json output files.
# Single file
code-to-figma scan src/components/Button.tsx
# Glob (quote to prevent shell expansion)
code-to-figma scan "src/components/**/*.tsx"
# Custom output directory
code-to-figma scan src/components/Button.tsx -o my-figma-data
# Watch mode — re-scans on save
code-to-figma scan "src/components/**/*.tsx" --watchOptions:
| Flag | Default | Description |
|------|---------|-------------|
| -o, --output <dir> | .figma | Output directory for .figma.json files |
| -w, --watch | off | Watch files for changes |
Output: <outputDir>/<ComponentName>.figma.json per component
What it extracts:
name— component nametype—COMPONENT_SET(has variant prop) orCOMPONENTvariants— one entry per string-literal value in the variant unionstyles— layout (flex direction, gap, padding) + typography (family, size, weight)autoLayout— Figma auto-layout settings (mode, wrap, alignment)props— all destructured props withtype(from TS unions) andvariantPropertyflagtokens— CSS token names found in className stringsframe.cornerRadius— fromrounded-*classesframe.width/height— inferred from font-size + padding
Variant detection: The parser reads TSInterfaceDeclaration and TSTypeAliasDeclaration nodes to extract actual union literal values. For example:
interface ButtonProps {
variant?: "primary" | "secondary" | "destructive";
}Produces three variants: primary, secondary, destructive. Falls back to generic names (default, primary, secondary, outline) if no TypeScript types are found.
plugin-output
Bundle multiple .figma.json files into a single plugin-data.json array for the Figma plugin.
code-to-figma plugin-output
code-to-figma plugin-output -i .figma -o plugin-data.jsonOptions:
| Flag | Default | Description |
|------|---------|-------------|
| -i, --input <dir> | .figma | Directory containing *.figma.json files |
| -o, --output <file> | plugin-data.json | Output file path |
Output: JSON array of FigmaJsonOutput objects, ready to paste or load in the plugin.
Example output summary:
✓ Button.figma.json — COMPONENT_SET, 3 variant(s)
✓ Badge.figma.json — COMPONENT_SET, 4 variant(s)
✓ Card.figma.json — COMPONENT, 1 variant(s)
Bundled 3 component(s) → plugin-data.json
Next: Load plugin-data.json in the Figma pluginread
Read components and styles from an existing Figma file via the REST API.
code-to-figma read --file-key ABC123
code-to-figma read --file-key ABC123 --node-id 1:234
code-to-figma read --file-key ABC123 -o figma-read.jsonRequires figmaAccessToken in .code-to-figma.json (or FIGMA_ACCESS_TOKEN env var). This command is for reading from Figma, not writing to it.
Configuration
.code-to-figma.json:
{
"figmaFileKey": "ABC123",
"figmaAccessToken": "figd_...",
"componentGlob": "src/components/**/*.tsx",
"outputDir": ".figma",
"framework": "react",
"styling": "tailwind",
"adapter": "tailwind-v3",
"tokenMapping": {
"--color-primary": "brand/primary",
"--space-4": "spacing/4"
},
"parserOptions": {
"extractVariantsFromProps": true,
"detectClassNameUtilities": true,
"extractSpacing": true
}
}| Field | Default | Description |
|-------|---------|-------------|
| figmaFileKey | "" | Figma file key for read command |
| figmaAccessToken | "" | Personal access token for read command |
| componentGlob | "src/components/**/*.tsx" | Default glob for scan |
| outputDir | ".figma" | Where .figma.json files are written |
| framework | "react" | Parser mode (react only currently) |
| styling | "tailwind" | Styling system to resolve |
| adapter | auto | Explicit adapter override: tailwind-v3, tailwind-v4, shadcn, shadcn-v4, radix, base-ui |
| tokenMapping | {} | Map CSS custom properties to Figma token paths |
| parserOptions.extractVariantsFromProps | true | Detect variant prop unions |
| parserOptions.detectClassNameUtilities | true | Parse Tailwind className strings |
| parserOptions.extractSpacing | true | Extract padding/gap values |
Supported Patterns
| Pattern | Status |
|---------|--------|
| Static className="..." strings | ✅ Full |
| TypeScript literal union props ('a' \| 'b') | ✅ Full |
| Template literals — static parts + single-identifier union interpolation | ✅ Full |
| cn() / clsx() — static strings, ternary branches, logical && args | ✅ Full |
| Inline style={{ backgroundColor, color, fontSize, fontWeight, borderRadius }} | ✅ Full |
| Arrow function + React.FC<Props> | ✅ Full |
| Function declaration components | ✅ Full |
| interface Props + type Props — prop type inference | ✅ Full |
| Watch mode (--watch) with unlink cleanup | ✅ Full |
| FIGMA_ACCESS_TOKEN env var for read command | ✅ Full |
| CSS Modules (className={styles.button}, cn(styles.a, styles.b), styles[variant]) | ✅ Full |
| CSS composes: directives (same-file and cross-file) | ✅ Full |
| Direct JSX ternary className={a ? 'x' : 'y'} | ✅ Full |
| styled-components / @emotion/styled — static template literals (no ${}) | ✅ Partial |
| CSS-in-JS with runtime interpolations | ❌ Not supported |
See ../../code-to-figma/references/SUPPORTED.md for detailed examples.
Programmatic API
import { scanFile, pluginOutput, generateFigmaJson, parseComponent } from "@kylebrodeur/code-to-figma";
// Scan a file
await scanFile("src/components/Button.tsx", ".figma", config);
// Bundle for plugin
await pluginOutput({ input: ".figma", output: "plugin-data.json" });
// Low-level: parse then generate
const parsed = await parseComponent("Button.tsx", config);
const json = generateFigmaJson(parsed, config);Development
cd packages/cli
# Build (tsc)
pnpm build
# Watch
pnpm dev
# Typecheck only
pnpm typecheckQuick Start
# Install globally
npm install -g @kylebrodeur/code-to-figma
# Or use npx
npx @kylebrodeur/code-to-figma init
npx @kylebrodeur/code-to-figma scan src/components/Button.tsx
npx @kylebrodeur/code-to-figma plugin-output -i .figma -o plugin-data.jsonArchitecture
React Component → Parser → Figma JSON → Figma Plugin → Figma Canvas
↑______CLI_______↑ ↑______Plugin_____↑Two-part system:
- CLI (this package) — Parses React/Tailwind, generates
.figma.json - Figma Plugin — Reads JSON, renders frames with auto-layout
Workflows
Workflow A: Code-First (Greenfield)
1. Build component in React
2. code-to-figma scan → generates .figma.json
3. Plugin imports to Figma
4. Designers polish in Figma
5. Future updates: re-scan → re-import in pluginWorkflow B: Figma-First (with Code Connect)
1. Design in Figma
2. Code Connect → generates React
3. Implement in code
4. (Optional) Read components via `code-to-figma read`Commands
| Command | Purpose |
|---------|---------|
| init | Create .code-to-figma.json config |
| scan <file> | Parse component to .figma.json |
| scan --watch | Watch and re-scan on change |
| read | Read components/styles from Figma via REST API |
| plugin-output | Generate plugin-compatible JSON bundle || token add -k <key> -p <path> | Add or update a token mapping |
| token remove -k <key> | Remove a token mapping |
| token list | List all token mappings |
| token clear | Remove all token mappings |
Configuration
.code-to-figma.json:
{
"figmaFileKey": "ABC123",
"figmaAccessToken": "figd_xxx",
"componentGlob": "src/components/**/*.tsx",
"tokenMapping": {
"--color-primary": "primary/500",
"--space-4": "spacing/4"
},
"outputDir": ".figma",
"framework": "react",
"styling": "tailwind",
"adapter": "tailwind-v3",
"parserOptions": {
"extractVariantsFromProps": true,
"detectClassNameUtilities": true
}
}Tip: Token mappings can be managed without editing this file — use
code-to-figma token add -k "--color-primary" -p "color/primary".
Integration with ux-collab
Add to your .ux-collab.md:
codeToFigma:
enabled: true
cliCommand: "npx @kylebrodeur/code-to-figma"
outputDir: ".figma"
onBuild: trueFigma Plugin Setup
- Install plugin from Figma Community: "Code to Figma"
- Or development: Load
plugin/folder in Figma Desktop - Plugin reads from JSON files or REST API
License
MIT
