Skip to content

RiteshYadavCNB/figma-to-code-plugin

Repository files navigation

React Codegen — Figma Plugin

Generate production-ready React + styled-components code directly from any Figma frame. The plugin runs in Dev Mode, analyses your component structure, and produces two parallel panels of code you can copy straight into your codebase.


What it generates

Pattern detected Component output Styles output
Carousel / Slider useState with prev/next/dots + autoPlay Container, Track, Buttons, Dots
List Maps items[] prop with empty state ul + item wrappers
Grid CSS Grid with configurable columns Auto-detected column count
Card Props for text, image, CTA, icon article with all child styles
Navbar logo, links[], optional CTA prop nav, links list, button
Hero heading, subheading, two CTAs, backgroundImage Full-bleed section with z-layering
Tabs useState + TabItem[] with accessible roles Tab list, buttons with $active prop
Form useState per field + onSubmit handler Input, Textarea, Label, Submit
Generic Tree-walking JSX + auto text/image props All child nodes as styled components

Setup

Prerequisites

  • Node.js 18+
  • Figma desktop app (Dev Mode requires a paid plan or free Dev Mode access)

Install & build

npm install
npm run build       # production build → dist/
npm run watch       # development watch mode

Load in Figma

  1. Open Figma desktop → PluginsDevelopmentImport plugin from manifest...
  2. Select manifest.json from this folder
  3. Switch to Dev Mode in the toolbar (the </> icon)
  4. Select any frame → open the Inspect panel → choose React + Styled Components from the language dropdown

Project structure

figma-codegen-plugin/
├── manifest.json          # Plugin manifest (editorType: dev, codegen capabilities)
├── webpack.config.js      # Two bundles: sandbox code + UI iframe
├── tsconfig.json
├── src/
│   ├── code.ts            # Main thread: codegen event → analyse → generate → postMessage
│   ├── analyser.ts        # Detects pattern from node tree (carousel, list, grid…)
│   ├── styleExtractor.ts  # Reads Figma node properties → CSS values
│   ├── generator.ts       # Pattern-specific React + styled-components generators
│   ├── ui.html            # Plugin iframe HTML (split panel UI)
│   └── ui.ts              # Iframe script: receives code, renders it, handles copy
└── dist/                  # Built output (committed or gitignored — your choice)
    ├── code.js
    ├── ui.html
    └── ui.js

How it works

User selects frame in Figma Dev Mode
         │
         ▼
figma.codegen.on('generate', { node })   ← fires on every selection change
         │
         ├─→ analyser.ts          Walk node tree, detect pattern + repeating children
         │
         ├─→ styleExtractor.ts    Read fills, strokes, layout, typography → CSS values
         │
         ├─→ generator.ts         Pattern dispatcher → build JSX + styled-components strings
         │
         ├─→ CodegenResult[]      Returned to Figma's native Inspect panel (2 sections)
         │                        Section 1: Component code (TYPESCRIPT)
         │                        Section 2: Styled-components (TYPESCRIPT)
         │
         └─→ figma.ui.postMessage → ui.ts renders split-panel view with syntax highlight + copy

Two outputs, two places

Figma's native Inspect panel — two collapsible code sections appear automatically. Each has Figma's built-in copy button.

Plugin panel (custom UI) — a split-panel view with:

  • Syntax-highlighted code
  • Tab switching: Split / Component only / Styles only
  • Copy buttons per panel with confirmation feedback
  • Status bar showing detected pattern + component name

Pattern detection logic

The analyser scores each node based on:

  1. Layer name keywordscarousel, slider, hero, nav, header, form, grid, tab etc.
  2. Layout modeHORIZONTAL layout + 2+ repeating children → carousel; VERTICAL → list
  3. Repeating children — groups nodes by type and finds the largest group of identical siblings
  4. Child content — presence of text nodes, image rectangles, button-named frames

Detection priority (most specific wins):

carousel > tabs > navbar > hero > form > grid > list > card > generic

Preferences

Accessible via the gear icon in Figma's Inspect panel:

Preference Options Effect
Tab Size 2 / 4 Indentation in generated code
Units px / rem All dimension values (16px vs 1rem)

Generated code conventions

  • Files: ComponentName.tsx + ComponentName.styles.ts
  • Exports: Named styled-components exports, default component export
  • Props: Derived from layer names — text layers become string props, image rectangles become imageSrc / imageAlt
  • Repeating children: Become typed ItemData[] interface passed as items prop
  • Transient props: Boolean/variant styled-component props use $ prefix (e.g. $active) per styled-components v5+ convention

Tips for better output

Figma practice Why it helps
Name your layers meaningfully Layer names become component names, prop names, and styled-component names
Use Auto Layout Enables correct flexDirection, gap, padding extraction
Group repeating items The analyser needs 2+ identically-typed siblings to detect lists/grids/carousels
Name image layers with "image", "photo", "thumbnail" Generates as="img" with src/alt props instead of a blank div
Name button groups with "button", "btn", "cta" Generates onClick handler props
Use solid fills (not gradients) for backgrounds Only solid fills are extracted to backgroundColor

Limitations

  • Gradient fills are not converted (complex CSS gradients from Figma data are lossy)
  • Component instances are treated as regular frames — Figma component variables are not yet mapped to props
  • Images inside fills (Figma image fills on rectangles) are detected by layer name, not fill type
  • Auto Layout gaps require Figma's itemSpacing property — absolute-positioned designs lose flexbox semantics
  • The 3-second codegen timeout — extremely deep or complex frames may hit Figma's limit; the plugin handles this gracefully by returning what it has

Development

# Watch mode with source maps
npm run watch

# Type check only
npx tsc --noEmit

# Production build (minified, no source maps)
npm run build

To add a new pattern:

  1. Add the pattern name to ComponentPattern in analyser.ts
  2. Add detection logic in analyseNode()
  3. Add a generator function in generator.ts
  4. Register it in the GENERATORS map at the bottom of generator.ts

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages