From Figma Design System to React Library: A Quick Tutorial in the PR Loop
Connect Claude Code to your Figma design system, turn Tailwind buttons and toggles into real React, and house them in a Vercel-hosted library with a proper PR workflow.
Most product teams maintain a design system in two places that are both real, and both usually tended by people who care. There's the Figma library, where designers shape variants, tokens, and the craft of the set. And there's the coded library, where those same components become interactive software, often with a living preview surface like Lookbook, Storybook, or a peer tool that anyone on the team can open without cloning a repo. The recurring industry problem isn't that one side is abandoned. It's sync and participation: as tokens and components evolve, Figma and the coded source of truth can diverge unless designers and engineers share a deliberate loop between them.
This tutorial tightens that loop from the designer's side, quickly. You'll connect Claude Code directly to your Figma file, turn your button components into a real React button (with hover, focus, press, and disabled states you can exercise in the browser), house it in a GitHub repo, deploy it as a live component lab on Vercel, and then, the part that matters most, ship your next component through an actual pull request with a preview URL. That last loop is the design engineer workflow in miniature, and by the end you'll have run it once end to end. Along the way I'll also map where Lookbook and its peers fit, how teams choose among them, and how to bring designers into the coded side without asking anyone to become an engineer overnight.
If you did my previous tutorial (https://elliotrylands.com/notes/figma-to-live-url-designers-first-real-code) you already have everything installed and this will move fast. If not, you need three things from it: Node.js from nodejs.org (https://nodejs.org), Claude Code (npm install -g @anthropic-ai/claude-code), and free GitHub and Vercel accounts. Fifteen minutes, one time.
And this isn't hypothetical. I ran the exact workflow below against a Tailwind component set in Figma: seven button hierarchies, five sizes, destructive and dot-leading variants, then shipped a Toggle through a real PR, then a GOV.UK theme through a second PR, all pulled through MCP into a living repo. Here is the destination first. The lab is live on this page. The public repo is underneath it. Flip the states, try the GOV.UK theme, copy the JSX, then follow the steps to build your own.
Live result
Component Lab
Tailwind Buttons and Toggles from a Figma pull: hover, focus, press, disabled, and a keyboard-ready switch. Flip GOV.UK to see the token layer swap. Click to copy JSX.
Why a living component lab matters
The lab we're building here is a small member of a large family: a designed gallery where every variant is rendered live, every state is triggerable, the JSX copies on click, and theming is a token flip (try the GOV.UK flavour). Anyone with the URL can click the actual buttons and switches. If your team already has Lookbook, Storybook, or similar, treat this lab as practice for that world, not a replacement for it. The skill you're rehearsing is the sync loop: Figma in, coded component out, reviewable PR in between.
Lookbook, Storybook, and choosing a coded surface
Most teams already have somewhere coded components can be seen. Lookbook is a strong fit for Rails apps built with ViewComponent and related Ruby UI patterns: it sits close to the application and gives you Storybook-like browsing without pretending the frontend is a separate SPA. Storybook is the common choice across React, Vue, Angular, and web-component stacks. Ladle is a lighter, Vite-native alternative when you want React stories without Storybook's full surface area. Histoire plays a similar playground role for Vue and Svelte. Longer-lived HTML-first systems still use pattern libraries like Fractal or Pattern Lab. On the documentation and governance side, teams often add zeroheight, Supernova, or Knapsack so guidelines, tokens, and usage live somewhere designers actually open. Underneath many of those setups sits Style Dictionary (or a similar token pipeline) turning design tokens into platform-ready code.
None of these is the right tool in the abstract. You choose for stack fit, who will maintain previews, and how a designer finds the coded truth on a Tuesday afternoon. A few practical considerations:
If the product is Rails plus ViewComponent, Lookbook usually meets you where the code already lives, which is why so many teams in that stack prefer it to bolting Storybook onto server-rendered components. If the coded system is React-first or multi-framework JavaScript, Storybook or Ladle is often the path of least resistance, with Chromatic-style visual review available when you need it. If the pain is stakeholder-friendly guidelines more than isolated component development, a docs platform such as zeroheight, Supernova, or Knapsack may matter as much as the explorer. If tokens are the bottleneck, invest in the pipeline (Style Dictionary and friends) before inventing another gallery. Custom labs, like the one in this tutorial, earn their keep for learning, demos, and portfolio proof. Adopting Lookbook, Storybook, Histoire, or a docs platform is usually wiser once a team needs shared ownership, contributor conventions, and a URL everyone already bookmarks.
Building your own versus adopting something established is the other fork. A homemade gallery teaches the loop and can be enough for a small experiment or a hiring-facing artifact. Lookbook, Storybook, Ladle, Histoire, zeroheight, Supernova, and Knapsack buy patterns other people have already paid for: preview hosting habits, accessibility addons, token sync, and a contribution culture. The expensive path is inventing a third source of truth that neither designers nor engineers treat as canonical. Prefer one coded surface the team agrees to keep honest, then spend your energy on the Figma-to-code loop rather than on a rival docs site.
Team shape changes the bet. A large design org rarely needs every designer opening pull requests on day one; it needs a few system partners who live in Lookbook or Storybook, bring preview links into critique, and widen the circle as the ritual gets familiar. A contractor or freelance designer can still raise the quality of a handoff by naming which stories should update and, when possible, attaching a preview URL, without joining the client's release train. An individual design engineer working with a team of designers is often the ladder: translate Figma decisions into reviewable changes, invite comment before merge, and make the coded surface feel like a design tool rather than an engineering attic. A small product trio may find a lightweight lab enough until Storybook or Lookbook earns its keep. In every shape, the goal is the same: designers influencing the coded system as partners, and engineers getting clearer intent instead of another static handoff.
Step 1: Connect Claude to your design system (five minutes)
Claude Code talks to Figma through Figma's official MCP server, which is a bridge that lets the agent read your files: components, variants, variables, styles, the lot. Setup is one command now. In your terminal:
claude plugin install figma@claude-plugins-officialRestart Claude Code, type /plugin, select the figma server under Installed, and click "Allow access" when the browser asks. That's it. From now on, when you paste a Figma link into a Claude Code prompt, it doesn't squint at a screenshot. It reads the file: exact fills, exact type styles, exact variant structure, your actual variables. (Figma's setup guide (https://help.figma.com/hc/en-us/articles/39888612464151-Claude-Code-and-Figma-Set-up-the-MCP-server) covers a desktop-app variant for enterprise plans, but the command above is the one most people need.)
This is the "connect Claude to my design system" moment, and it's worth pausing on what it means. Your Figma file just became a data source. Every carefully named variant and token you've maintained is now machine-readable design intent, and the quality of your Figma hygiene is about to pay compound interest. Some organisations put that connection behind MCP gateways like Runlayer, Arcade, or Obot for access control, audit, and security review. Same bridge, tighter front door.
Step 2: Scaffold the lab (three minutes)
Same scaffold as last time, new name:
npm create vite@latest component-lab -- --template react
cd component-lab
npm install
npm run devLeave the dev server running at localhost:5173, open a second terminal, cd component-lab, and start claude.
Step 3: Pull your first component out of Figma
In Figma, select your button component set (the parent with all the variants in it), right-click, Copy link to selection. Now prompt, pasting your link where mine is:
Read this Figma component set: [YOUR FIGMA LINK]
Build it as src/components/Button.jsx with styles in src/styles/tokens.css
and src/components/button.css.
Rules:
- Map the Figma variant properties to props: hierarchy (primary | secondary-gray |
secondary-color | tertiary-gray | tertiary-color | link-gray | link-color),
size (sm | md | lg | xl | 2xl), destructive, showDot. Match my Figma naming.
- Pull the color, radius, spacing and type values into CSS custom properties in
tokens.css (--primary-600, --radius-md, etc). No hardcoded values in button.css.
- Real interactive states, not variant swaps: :hover, :focus-visible with a visible
ring, :active with a subtle press, disabled at reduced opacity with no pointer
events.
- It renders a real <button> element with type="button" as default.
- Transitions at 150ms ease-out.Watch what comes back, then flip to the browser. Here's the payoff hiding in that prompt: Figma can document hover, focus, and press as variants, and careful teams do. The coded button lets you exercise those states for real. Tab to it and the focus ring appears. Hold the mouse down and it presses. Flip destructive and the error palette takes over. That gap between documenting a state and feeling it in the browser is exactly why Figma and the coded library both earn a place. If a state feels wrong, say so like a design review ("the press state is too much, drop the translate to 0.5px") and watch it land in seconds.
Here's what that looked like when I ran it for real. My button set was a Tailwind kit, which is about as disciplined as Figma files get: variant properties named Hierarchy, Size, Destructive, State. The agent read the set through MCP and came back with a Button whose props mirror the file exactly, seven hierarchies from primary down to link-color, five sizes from sm to 2xl, and a tokens.css where Primary/600 became --primary-600: #7f56d9 with the file's actual focus-ring shadows alongside it. The naming did the work: because the Figma properties were clean, the React API came out clean, with nothing to rename after the fact.

A word on file hygiene, because real component sets vary. If variants are still named "Property 1=Default, Property 2=Big", the agent will faithfully build props called property1. Two minutes of renaming in Figma before you copy the link (variant properties as variant and size, values as the words you'd want in code) gives you an API you'll be happy to document. The same goes for detached instances and hardcoded hex values where a style would serve better. The MCP connection is a mirror: it reflects the discipline already in your file straight into the codebase, which makes this tutorial a useful check on naming and tokens too.
No component set handy? Describe your dream button in the same structure (variants, sizes, tokens, states) and the tutorial works identically. The Figma link is the better habit, though, because it keeps your file as the source of truth.
Step 4: Build the lab page
Next prompt:
Replace App.jsx with a component lab page:
- Header: "Component Lab" and a one-line description.
- A Buttons section: a grid showing every hierarchy x size combination, plus a row
demonstrating destructive, dot-leading, and disabled.
- Clicking any example copies its JSX snippet to the clipboard and shows a small
"Copied" toast.
- Style the page itself with the same tokens. It should feel designed, not like
a test harness: generous spacing, max-width 960px, clear section labels.Two prompts in, and you have a living reference where the components prove themselves, the same job Storybook and Lookbook do for mature coded systems. Poke at it. Fix what offends you. This page is now your design QA environment, and every future component gets judged in it.
Step 5: House it properly, then let Vercel watch the repo
In your Claude Code session:
Create a git repo, write a README that explains what this lab is and links to the
live URL placeholder, commit everything, create a public GitHub repo called
component-lab, and push.Now the important housing decision. Last time we deployed with the vercel command. This time, connect the repo instead: go to vercel.com/new (https://vercel.com/new), import component-lab from your GitHub, accept the defaults, deploy. Sixty seconds later you have your live URL, but that's not why we did it. Connecting the repo means Vercel now watches GitHub. Every push to main deploys automatically. And every pull request gets its own temporary preview URL. That second behavior is about to become your favorite thing in this entire workflow.
Step 6: Ship the next component like a design engineer
Here's the loop that separates "I made a repo once" from doing the job. We'll add a Toggle component, properly. In Claude Code:
Create a branch called feat/toggle. Then read this Figma component:
[LINK TO YOUR TOGGLE COMPONENT]
Build src/components/Toggle.jsx using only existing tokens from tokens.css,
with sm/md sizes, label + supporting text, pressed/hover/focus/disabled states,
and role="switch". Add a Toggles section to the lab page with the same copy-JSX
behavior. Commit with a clear message, push the branch, and open a pull request
titled "Add Toggle component" with a description of what changed.Give it a minute, then open the PR on GitHub. Sitting in the comments: a Vercel preview URL. Click it. That's your lab with the new Toggle, deployed to its own temporary address, while main and your production URL remain untouched.


Sit with how good this is as a design review tool. You can send that preview link to another designer and ask "does this focus state match Button?" before anything ships. You can compare production and preview side by side in two tabs. Critique happens against real, interactive components at a shareable URL, without asking reviewers to install anything. When you're satisfied, click Merge on GitHub. Vercel notices, rebuilds, and your production lab has a Toggle about ninety seconds later. The PR itself becomes a record too: six months from now, "why does Toggle use this track color?" has an answer with a date, a diff, and the preview everyone approved, a paper trail that sits nicely alongside Figma version history. Branch, build, preview, review, merge, deploy. You just ran the exact ceremony a design engineer runs, and none of it required writing code by hand.
Step 7: Prove theming is just another PR
One more loop, this time without inventing a new component. Theming should be a token contribution, not a fork of every button. In Claude Code:
Create a branch called feat/govuk-theme. Add src/styles/govuk-theme.css that
scopes govuk-frontend values under .theme-govuk (green primary, square corners,
2px bottom shadow, yellow focus, Arial fallback). Import it from index.css.
Add a "Theming: GOV.UK flavour" section to the lab that toggles the scope on the
same Button and Toggle components. Commit, push, and open a pull request titled
"Add GOV.UK theme".Same ceremony as Toggle: preview URL on the PR, green Start now and yellow focus on tab, then merge. Production picks up the theme section without rewriting a single component file. That is the point of the token layer: Tailwind is the default skin, Toggle proved a new component can ship through review, and GOV.UK proves a new brand can ship the same way.
The finished repo, and the space it leaves open
Here's what the system repo holds after one afternoon (same one linked at the top of this note). A tokens.css that is the Figma variables, machine-translated, so every component that follows is forced onto the same palette and type scale. A Button covering the full Tailwind matrix with real states. A Toggle that shipped through the PR flow, with proper role="switch" semantics so it works from a keyboard, behavior the coded library is uniquely placed to prove. A GOV.UK theme that shipped through a second PR, proving theming is just another contribution: same components, swapped token layer. And a gallery page where all of it demos itself, every example click-to-copy.

Just as important is what the repo doesn't hold yet. The components folder has obvious empty seats: Input, Badge, the social login buttons, whatever your product leans on. That's not unfinished, that's the design. A system repo earns its keep by making the next contribution cheap, and this one makes it a pattern you've already run: branch, point the agent at the next Figma node, build with existing tokens only, PR, preview, merge. The Toggle PR took a fraction of the Button work, and the GOV.UK theme PR was quicker still, because the conventions compound.
This is also the part to put in front of people, because it reads as design engineering. Not "I know React" but something more specific and more useful: the tokens in the repo trace to variables in the design file, the component props trace to variant properties, and every change arrives through a reviewable PR with a live preview. Engineers recognize that discipline instantly, and it changes the conversations you get invited to. The benefits stack up quietly: Figma and the coded system stay easier to keep aligned because they share one source of truth; design review happens on real interactive states as well as the variants documented in Figma; accessibility stops being a handoff note and becomes something you shipped; and you develop an eye for exactly the gaps (naming, states, edge cases) that make handoffs expensive. The repo is simultaneously a working tool, a portfolio piece that demos itself, and proof you can operate on both sides of the divide.
Bring designers into the coded system, one rung at a time
Impact on the engineering side rarely starts with "learn to ship production packages." It starts with designers being present where the coded system is judged. A practical ladder looks like this.
Rung one: keep Figma as home base. That is still where most design craft happens, and pretending otherwise does not help. Rung two: bookmark the team's Lookbook, Storybook, Ladle, Histoire, or docs site, and once a week open a component you own. Compare variants, tokens, and states to the file. Note mismatches without blame; mismatches are the sync problem showing itself. Rung three: when engineers share a pull request or a Vercel-style preview URL, review it the way you review a Figma branch. Comment on focus, spacing, empty states, and whether the interactive behavior matches intent. Preview URLs are designed for this. Rung four: propose a small change you can own end to end, a token tweak, a missing state, a Toggle-sized component, and ship it through the same branch, preview, review, merge loop this tutorial teaches. That is how designers earn trust on the engineering side: not by replacing engineers, but by arriving with clearer intent, reviewable diffs, and respect for the coded source of truth.
How you climb depends on who you are on the team. In a large design org, start with a handful of willing system partners rather than a mandate for everyone. Put Lookbook or Storybook on the critique agenda the way you put Figma files on it. For a contractor or freelancer, the high-leverage move is a clean Figma delivery plus an explicit note about which coded stories or docs pages should update, and a preview link when you can produce one. For a design engineer embedded with designers, your job is hospitality: make the coded surface legible, bring previews into design conversations, and leave the door open for the first PR comment from someone who has never opened the repo. Engineers, for their part, make this possible when they treat designer comments on previews as design review, not as noise in an engineering channel. The best systems I've seen make that welcome explicit.
Stack a few more, then make it yours
Run the loop again for whatever your system needs next, and notice that the agent follows the patterns already in the repo, which means your early taste decisions keep paying off. Three or four components in, something shifts: the repo stops being a tutorial artifact and starts feeling like a credible sibling to the coded docs your team already trusts, because "clickable" here is literal.
A scope note, in the spirit of staying honest. This lab is a design tool and a proof of capability, and as those it's excellent. It is not yet the production package your engineering team imports; that path involves publishing, versioning, tests, and accessibility review beyond a focus ring, and it deserves engineers as partners. If your team already has Lookbook, Storybook, or similar, treat this as practice for contributing to that world, not a replacement for it. The move is to show them the lab and the PR flow and ask what it would take to keep Figma and the coded source of truth aligned as the system grows. That conversation, with a live URL and a merged PR as your credentials, goes very differently than "I had an idea about our design system."
Your buttons have opinions about how they should feel when pressed. Those opinions start in Figma; this loop helps them land in code without losing the craft. Play with the lab above, flip the GOV.UK theme, clone the repo, give yourself the afternoon, then send the preview link to the person you most want to surprise.
Would you open a PR on your own design system? If you run this loop, send me the preview URL. I am usually posting whatever I have been building on LinkedIn.
Find me on LinkedIn →