From Figma to production React, with AI in the loop

Designers have been promised "design-to-code" for years. What kept arriving was a button that exported a div soup nobody wanted to ship. The promise quietly stalled. Something has shifted in the last twelve months, and the workflow that comes out the other side is finally one a real team can use.
This post is for the designer who wants to stop throwing redlines over the wall, and for the developer who wants to stop translating Figma layers into JSX by hand. It is about a single loop: design in Figma using a kit that matches your React components one to one, then let an AI tool read the Figma file and produce code that already speaks the same language as your codebase. Both sides of the team work in their native tool. The AI does the translation step that used to be a tax on everyone.
Below is how the loop works, how to set it up on an existing project, and where to keep your hand on the wheel.
Why this loop is different now
Three things had to be true at the same time, and they finally are.
First, your design file has to use the same building blocks as your production code. Not a "Figma version of a button." The same button, with the same name, the same variants, the same prop surface, sitting in your Figma library and in your components/ui/ folder. shadcncraft is built around this constraint. The Figma kit and the React registry mirror each other component for component, slot for slot.
Second, the AI needs to see the design. The Figma MCP server exposes design files to AI tools the same way the file system is exposed to a code editor. Claude, Cursor, Codex, and friends can now read a frame, understand its structure, see the variables in use, and reason about it. This is what flipped the workflow. Until last year, AI tools could only see the screenshot. Now they can read the layers.
Third, the AI needs to recognise the components. The shadcn MCP server, plus shadcncraft's namespaced registry, means the AI is not generating React from scratch every time. It can pull the right component from your installed kit and compose with it. The generated code looks like it came from someone who already knew your conventions, because it did.
When those three pieces are connected, the loop runs like this: design a screen, ask the AI to implement it, get a first pass that uses your real components, refine in the editor. The translation step that used to take an afternoon takes a few minutes. The drift between design and code shrinks because both ends are pinned to the same kit.
The setup, end to end
There are four pieces to connect. Once they are in place you do not touch this part again.
1. shadcncraft installed in your React project
If your project already uses shadcn/ui, you are most of the way there. Add the shadcncraft registry to your components.json, set your license key in .env, and you can install any block or component with the standard shadcn CLI:
pnpm dlx shadcn@latest add @shadcncraft/header-1The full setup is in the Installation docs, including how to switch style presets and how to configure a team license.
2. The shadcncraft Figma kit, opened in Figma
Open the kit in Figma. This becomes your design library. Every block and component you can install in code has a matching counterpart here, with the same name and the same variants. Themes are managed inside the file using the shadcncraft Figma plugin, which can export shadcn-compatible CSS variables straight from your Figma file into your codebase. Your design tokens and your code tokens stop being two separate things to maintain.
3. The Figma MCP server, connected to your AI tool
Enable the Figma MCP server in Figma's settings, then point your AI tool at it. Cursor, Claude Code, VS Code, and Codex all support MCP servers. Once connected, the AI can read any Figma file you have open, including the shadcncraft kit and the screens you are designing on top of it.
4. The shadcn MCP server, also connected
The shadcncraft registry works with the shadcn MCP server out of the box. From your project root, run the init command for your editor of choice:
pnpm dlx shadcn@latest mcp init --client cursor
pnpm dlx shadcn@latest mcp init --client claude
pnpm dlx shadcn@latest mcp init --client vscodeWith both MCP servers connected, your AI tool can simultaneously read the Figma file (via Figma MCP) and install the right components from your kit (via shadcn MCP). This is the bridge.
If any of the four pieces are missing, the loop still works in a degraded form. You can build by hand without the AI, or use the AI without Figma MCP and lose the design context. But all four together is what makes this feel like a single workflow rather than four separate tools you keep tab-switching between.
The loop in practice
Here is what the loop looks like on a real task. Imagine you have an existing SaaS app, already built on shadcn/ui, and you need to add a billing settings page.
You open your Figma file. You compose the screen out of shadcncraft blocks: a page header, a settings nav, a plan summary card, an invoices table, a payment method block. Because these are real components from the kit, they already have the right tokens, the right spacing, the right empty and error states. You change copy, swap the plan tier, point the table at your real data shape. You spend maybe twenty minutes designing.
Then you switch to your editor and ask Claude something like:
"Build the billing settings page from the selected frame in Figma. Use the existing shadcncraft components in this project. Keep the existing route conventions and data fetching patterns from the user settings page."
Claude reads the Figma frame through the Figma MCP. It sees the shadcncraft layer names. Because shadcncraft's convention is for layer names to match the data-slot values in the React components, it knows that card-header becomes <CardHeader>, that tabs-trigger becomes <TabsTrigger>, and so on. It installs anything from the registry that is not already in your project, references your existing data fetching patterns, and outputs the page.
The first pass gets you most of the way there. You review the diff. You correct the things only you can correct: business rules, real data shape, copy that the design did not specify, edge cases the AI did not consider. You commit.
This is the part the previous generation of design-to-code tools never delivered. The code that comes out is not div-soup that you would never write yourself. It uses the same components you would have picked, with the same props, in the same composition. Because the AI did not invent the components from a screenshot, it composed them from your installed kit.
Where the loop breaks, and what to do about it
Honest answer: the loop is not a magic button. It works well when both ends are disciplined. Here is what to watch for.
The Figma file has to be built out of shadcncraft components, not custom shapes that happen to look like shadcncraft components. If your designer detached an instance to make a one-off tweak, the AI cannot see the underlying component anymore. It just sees a frame with some rectangles in it. The output will be generic JSX rather than your kit. The fix is mechanical: keep instances intact, use slots and variant properties to make changes rather than detaching.
The AI's output is a starting point, not a final commit. Treat it like a pull request from a fast but new contributor. Read it, run it, refactor anything that does not fit your codebase's conventions. The advantage is the speed of the first pass, not the elimination of review.
Drift is real, but it is now measurable. If you generate a screen today and the kit updates next month, your screen does not auto-update. This is the same problem any installed-not-imported registry has, and shadcncraft handles it the way shadcn does, with the update strategy in the docs. The point is that drift is now visible and resolvable, instead of being the permanent baseline.
When the AI picks the wrong component, the fix is usually a clearer name. If the same prompt keeps producing a Dialog when you wanted a Sheet, that is feedback about your naming, not about the AI. shadcncraft component names are public surface, and we update them when they consistently confuse tools or people.
Why this beats the previous attempts
Two reasons, both structural.
The first generation of design-to-code tools tried to be clever about screenshots. They read pixels and tried to infer structure. That works for a static rectangle and falls apart on anything stateful, anything responsive, anything composed of real primitives. By contrast, this loop reads the actual Figma layer tree and matches it to actual React components. There is no inference layer to get wrong.
The second is that the design file and the production code are pinned to the same source. Both sides use the same kit, with the same names, the same variants, the same tokens. The AI does not have to translate between two languages, it just has to assemble. That is the part AI tools are good at right now.
Bringing this into an existing project
You do not need to start over. You probably should not.
If your project already uses shadcn/ui, you can layer shadcncraft on top without ripping anything out. Components install side by side with your existing ones. Tokens align. Pick one screen on your roadmap, ideally one that is greenfield or due for a refresh, and try the loop end to end on that single screen. A settings page, a new onboarding flow, a billing card. Anything contained enough that you can compare the before and after honestly.
What you are looking for in that first screen is not a productivity number. You are looking for whether the loop feels like one workflow or four. If it feels like one, expand from there. If it feels like four, the most common culprit is that one of the four pieces is not actually connected, usually the Figma MCP. Worth ten minutes to check.
If you want a place to start, the Installation docs cover the project side and the shadcn MCP setup. The Figma kit and the Figma MCP setup live inside Figma itself. Pick a screen, set aside an afternoon, and see what comes out the other side.
The promise that designers and developers could ship from the same source has been around forever. This is the first time it has been true.


