I've been designing in Figma for years, and I love it. But lately I've been wanting more. I've grown tired of spending countless hours prototyping within Figma's interface. Yes, it works well for small interactions, but it takes so long for major applications. So I started experimenting with turning Figma files into real, working prototypes using Cursor.
My first thought: this is either going to be magic or a total mess.
Spoiler: it works surprisingly well... "Why didn't I try this sooner?" well.
Why try this method?
Figma prototypes are great for showing the idea. But a prototype built in code does something Figma can't quite pull off: it lets people see the product in action.
- Developers see how things actually work. Menus, navigation, and interactions behave the way they will in the real thing, so there's less guesswork at handoff.
- Stakeholders get something real to react to. Instead of "imagine this part works," they can click around and feel it.
- You can test with users before development starts. That means catching problems while they're still cheap to fix, not after they're already built.
And honestly, building all of that by hand in Figma would take forever. Every interaction, every state, every connection.
How I Did It
Here's the setup I landed on. It looks like a lot of steps, but most of them you only do once.
- Install Cursor on your laptop.
- Install GitHub Desktop on your laptop.
- Install the Figma plugin inside Cursor and authenticate your account.
- Open your Figma file in Dev Mode and select Set Up MCP Server. This is what lets Cursor actually "see" your designs.
- Head back to Cursor and have it build out the screens you've selected.
- Iterate on the prototype until it's working like you want it to (note: this is the tedious part).
- Connect Cursor to GitHub.
- Create a repo in GitHub and turn on GitHub Pages so the prototype gets its own live link.
- Push the prototype to GitHub from Cursor.
And that's it! You end up with a real, clickable prototype with a link you can share with anyone. There's something so satisfying about sending someone a link and knowing they'll see exactly what you intended, in action.
One note: you'll need paid GitHub and Cursor accounts for this. But it's a drop in the bucket compared to the time you'd spend prototyping by hand in Figma.
Reality Check: It Took a Few Rounds
I'd love to say I followed those steps and a perfect prototype popped out the other side. It did not.
The first version was a decent start, but it was clear pretty quickly that Cursor needed more direction from me. So I went back in and started getting specific:
- Tweaking the designs. Some screens needed adjustments once I saw them working, so I had Cursor modify things.
- Spelling out the design system. I gave clearer instructions about which design system the files were built on and how its components and tokens should be used, so it stopped improvising its own versions of things.
- Setting up the demo data. I explained exactly how I wanted data entered and displayed for the demo, so the prototype showed realistic content instead of placeholder filler.
Each round got it closer. It took multiple passes of reviewing, clicking through, spotting what felt off, and giving more precise direction before it was working decently. But I'll be honest: watching it come together a little more each round was half the fun.
That's not so different from any design process. The first draft is rarely the final one.
And those rounds taught me the biggest lesson of all: the more structure and clarity I gave it, the better the result. Which brings me to the nerdy part.
Okay, Let's Get Nerdy
Here's the part that makes this work, and the part most "look what I built" posts skip: the design system. (Fair warning: this is where I get really excited.)
My working files aren't a pile of one-off components. They're connected to an attached design system library, and everything in them is built from it: components, variables, and tokens. That's what lets the prototype come out built from the same parts I designed with, instead of a rough approximation. Through the Figma MCP server, Cursor gets the actual structure: the layer hierarchy, auto layout, the components being used, and the variables behind every value.
Variables and tokens are the secret sauce. I set my system up in layers:
- Primitives are the raw values: the color scales like gray-900 and brand-600, plus a spacing scale built on a 4px base.
- Semantic tokens point to those primitives and describe what they're for: text-primary, border-primary, spacing-xl, radius-md. The best part is that each one holds a light-mode and a dark-mode value, so text-primary is a dark gray in light mode and flips to near-white in dark mode without touching a single component.
Because the prototype pulls in semantic tokens instead of hex codes, the code reads like a real codebase: CSS custom properties with meaningful names instead of hard-coded values scattered everywhere. Change the token once, and it updates everywhere. Same as in Figma.
Components carry the logic. A button in my design system isn't just a rectangle with text on it. It's a component with properties: variants for size and hierarchy (primary, secondary, tertiary), booleans for things like "has icon," instance swaps for which icon, and states like default, hover, focused, and disabled. When those properties are set up cleanly in Figma, they translate almost one-to-one into props in code: size="sm", hierarchy="secondary", isDisabled.
And because the states are already designed, the build knows what a dropdown looks like open vs. closed, or what a nav item looks like when it's active. That's how menus and navigation come out behaving like real UI instead of looking like pictures of it.
Garbage in, garbage out. Here's the honest truth: this only works as well as your file hygiene. The things that made the biggest difference for me:
- Auto layout everywhere. It maps almost directly to flexbox, so spacing and alignment survive the trip into code.
- Clear, consistent names. For layers, components, and properties. "Frame 427" tells the build nothing. "Nav item / Active" tells it everything.
- No detached instances. A detached component is just loose shapes, and it loses its connection to the system.
- Variables bound to properties, not typed in by hand. If a color is typed as a hex code instead of linked to text-primary, the build has no idea it's part of your system.
If your file is tidy, the prototype is tidy. If your file is chaos, well… you'll get a very faithful reproduction of the chaos.
Let's be real: clean files are hard. Deadlines happen. Someone asks for "just one quick change," and suddenly there's a detached instance with a one-off tweak in an otherwise perfect screen. Nobody sets out to make a messy file. It happens.
In a static workflow, that mess stays mostly hidden. When a clean file means a better prototype, tidying up finally feels worth it.
It's a loop, not a handoff. The old way was linear: design, hand off to dev with notes, and hope for the best. With the design system as the shared source of truth, it becomes a loop. I can design in Figma, build in Cursor, notice something feels off once it's actually clickable, and go back and fix it at the system level. I can iterate on behavior, not just layout.
The Takeaway
The design thinking still happens in the design. The tokens, the components, the structure: those are decisions I made, and this workflow just carries them into code faithfully. The better the system, the better the prototype.
What I'm most excited about is the bigger picture, and I can't stop thinking about it.
For as long as I've been doing this work, there's been a gap between design and development. Designers hand off static files and notes. Developers interpret them. It's a clunky system at best.
This workflow shrinks that gap in a real way. When a designer can hand off something that already works, the whole conversation changes. Instead of "what should this menu do?" it becomes "here's how the menu works, does it feel right?" Developers get a head start built on the same tokens and components they'll use in production. Stakeholders stop nodding along to mockups and start giving real feedback. And we can test it with users before real work begins.
I'm curious how far we can take this. A few things I want to explore next:
- Making clickable prototypes a standard part of design reviews
- Tighter connections between Figma components and the real code components developers already use
- Testing with users earlier and more often, with prototypes that feel like the real thing
- Getting designers and developers working from the same source of truth from day one
Working this way gives designers and developers a shared language and a lot more time to spend on the parts that really matter. I can't wait to keep learning, keep building, and share what comes next.