This article is a reflection on a challenge many designers now face in product design: building high-fidelity, interactive prototypes for genuinely complex interfaces, and what happens when the tools expected to solve that problem fall short. It also makes a case for a workflow that, while it might feel unfamiliar at first, is far more capable than anything Figma’s AI tooling currently offers.
- Figma Make breaks at complexity. Adding a table, a second page, or a dynamic chart is enough to cause it to stall — sometimes permanently. For data-driven enterprise interfaces, it is not a viable prototyping tool.
- The real alternative is the real codebase. Building prototypes directly in the front-end stack — using tools like Cursor — produces interfaces that behave exactly as the final product will, not just visual approximations.
- The setup takes one 15-minute screen-share with a developer. After that, the work is fully independent — no risk of breaking anything, no waiting on the dev team, and every change shows up live in the browser immediately.
- Figma and Jira plug directly into Cursor. MCP integrations let the AI read design files and pull ticket acceptance criteria without any manual copying or re-explanation.
- Cursor has three distinct modes — and using the wrong one wastes time. Ask, Plan, and Agent each serve a different purpose. Jumping straight to Agent on a complex task without planning first is one of the most common mistakes.
The promise and the reality of Figma Make
Figma Make is a Figma feature that uses AI to turn design ideas into interactive prototypes or UI outputs. In simple terms, it’s Figma’s attempt to bridge the gap between design and working interface using generative AI. It sounds like an appealing idea. You already have your designs in Figma, and with a few prompts, you should be able to bring them to life. For simple, single-page layouts, it can be a reasonable starting point. But the moment your interface grows in complexity, with resizable widgets, dynamic filters, conditional states, and real data, the cracks start to show.
Despite repeated attempts to break the interface down into smaller chunks, paste frames, convert components to images, and start fresh versions, Figma Make consistently got stuck. Loading would stall indefinitely. Elements would render incorrectly or not at all. At one point, even adding a table caused the tool to stop responding entirely.
One observation: Figma Make appears to work best on a single page with relatively simple content. Switching to a second page or adding a complex chart tends to degrade the output significantly. There is no way to separate concerns by starting a fresh chat for each UI element. Everything lives in one persistent context that becomes increasingly fragile as the design grows.
For complex, data-driven enterprise interfaces, that is simply not enough.
Prototyping in the real codebase
The alternative to Figma-based prototyping is to move directly into the front-end codebase and build interfaces in the same environment where the product actually runs. In this approach, tools like Cursor are used as AI-assisted coding environments to help implement UI components, interactions, and layouts based on existing designs.
This shifts prototyping from a visual approximation to a working implementation. The goal is to create high-fidelity prototypes that behave exactly as the final product will. Instead of simulating behaviour in a design tool, the prototype exists inside the real system, using the same components, data structures, and constraints as the final product.
For complex interfaces, this can improve fidelity. Interactions such as loading states, filters, conditional rendering, and multi-step flows behave realistically, rather than being approximated through design tool interactions.
This approach does require working more closely with the development setup, but the initial barrier is lower than it may appear.
Getting started: what the setup actually looks like
The entire initial setup requires a single 15-minute screen-sharing session with the front-end developer. After that, the work is entirely independent. If the project already has a developer playbook or a wiki, read it first, as it will typically contain setup instructions, environment variable examples, and context that saves a lot of time.
Initial installs and access
- Request access to the project’s GitHub organisation from the lead developer. Be explicit about what you need and ask for the minimum permissions required. There is no reason to have write access to the main or dev branches.
- Download and install Cursor from cursor.com. Sign up using your work email and log in. The free tier works for getting started, though an Ultra plan is recommended for heavier use.
- Download GitHub Desktop and sign in with your GitHub account. Once you are added to the organisation, your available repositories will appear. Clone the front-end repository to your local machine.
Opening and running the project in Cursor
- In Cursor, go to
File > Open Folder, then locate the front-end repository you cloned. - Open the Terminal in Cursor and run
git status. This confirms you are on the right branch and shows the current state of your working directory. - Run
git pullto fetch the latest content from the remote repository. - Check your Node.js version with
node --versionand confirm with the developer that you are using the same version as the team. Projects typically include an.nvmrcfile specifying the correct version. - Run
pnpm installto install all project dependencies. Ifpnpmis not yet installed, run these first:
sudo corepack enable
corepack prepare pnpm@latest --activate
pnpm -v
Enter your password when prompted, then runpnpm installagain. - Run
pnpm run devto start the development server. Open the local address in your browser, typicallylocalhost:3000orlocalhost:3001. UseCmd+Shift+Rfor a hard refresh if the preview does not load. If you run into issues, ask Cursor to help diagnose them. - Create your personal working branch — this is version control working in your favour. Nothing done here will affect the main or dev branches. Close the running terminal with
Ctrl+C, then run:
git status
git checkout -b [your-branch-name]
All your work stays on this branch. Nothing you do will affect the main or development branch. - Run
pnpm run devagain to restart the development server. You will need to do this each time you open the project.
With the dev server running and your branch created, you are ready to start building. At this point, you have a live, interactive preview of the front end in your browser that reflects the current state of what developers have shipped. From here, the workflow opens up significantly.
- If the project is mid-delivery, you will typically be layering your prototype on top of the existing codebase. Start with whatever screen or component you are currently designing. Pull the latest build from the dev team whenever a new sprint lands to keep your prototype in sync with their work.
- If the project is at an earlier stage, or you are starting from a largely empty codebase, the approach is the same: build screen by screen, component by component, using Cursor to implement what is already designed in Figma. You are not trying to produce production-quality code. You are producing a functional prototype that validates the design, surfaces edge cases, and gives stakeholders something real to react to.
What code-based prototyping unlocks
A few things become available to you at this stage that are not possible in Figma prototypes:
- Real or realistic data can be wired up — either from the actual backend, or mock data that mirrors the real data structure.
- Interaction flows can be validated end-to-end, including state changes, error states, and loading conditions that static prototypes simply cannot represent.
- A link can be shared with developers for review sessions — they get something real to inspect, not a Figma frame to interpret.
- The prototype can be connected to backend platforms later for testing with live data, though that step requires additional setup with the development team.
Instead of simulating behaviour in a design tool, the prototype exists inside the real system, using the same code components, data structures, and constraints as the final product.
How Cursor connects to your existing tools
One of the most significant advantages of Cursor over standalone AI tools is its ability to pull live context from the systems your team already uses. This is done through MCPs (Model Context Protocols), which are integrations that give the AI direct access to external tools via natural language — the same principle behind how AI agents understand and act on context from the systems around them.
Well-structured projects will already have a .cursor/ folder in the repository containing pre-configured MCP connections, design system components, project-specific AI rules, and specialist knowledge documents. When you open the project in Cursor, these load automatically. Ask the development team whether the project has this set up before configuring anything manually.
The Figma MCP allows Cursor to read your Figma files directly. Once connected, you can share a Figma URL in a prompt and ask the AI to implement a component based on the design spec. It can extract layouts, design tokens (colours, typography, spacing), and component structure without you having to manually copy anything.
To connect it, ensure you have a Figma account with access to the project files and that Dev Mode is enabled for those files. When you open the project in Cursor for the first time, a Figma authentication window will open. Approve access and confirm the connection is active under Settings, then Tools and MCP.
The Jira MCP allows Cursor to search issues, fetch ticket details, and pull in acceptance criteria and business logic that your BA has already written. This means you can reference a specific Jira ticket directly in a prompt, and the AI will factor all of that context into what it builds, without you having to re-explain it.
To connect it, generate a Personal Access Token from your Jira instance. Go to your Jira profile, locate Personal Access Tokens, and create one with at least read permissions. Add the token to a .env.local file in the root of the project. The MCP server will start automatically when you open the project in Cursor. Do not commit this file to the repository.
Beyond MCPs, well-maintained projects will also include AI rules, which are instructions the AI follows automatically for every interaction in that project. These might define code conventions, component patterns, or anything else the team wants the AI to consistently respect. There are also skills, which are specialist knowledge documents that the AI can load on demand for specific tasks.
From a designer’s perspective, these are worth knowing about because they mean the AI already understands the project’s conventions when you start working in it. You benefit from the groundwork developers have already done without having to set anything up yourself.
The three modes that keep Cursor under control
Cursor operates in three distinct modes, each designed for a different stage of the work. Understanding when to use each one is one of the most important habits to develop, and it affects the quality of the output.
| Mode | Purpose | Use for | What it can do |
|---|---|---|---|
| Ask | Clarifications and understanding | Reviewing docs, asking questions, understanding requirements | Read-only. No code changes, no external operations. |
| Plan | Design an approach before building | Breaking down features, proposing technical approaches, reviewing designs | Proposes changes and step-by-step plans. Does not execute anything. |
| Agent | Execute an approved plan | Making code changes, running commands, implementing features | Reads, writes, and edits files. Runs terminal commands. |
For complex tasks: use Ask to understand the existing code, Plan to design the approach and review it before anything changes, then Agent mode to carry it out. This separation prevents premature changes and keeps the process in control. For simpler, well-defined tasks where the approach is already clear, going straight to Agent is fine.
Choosing the right model for the task
Not every task requires the same model. Using a high-capability model for everything burns through tokens unnecessarily, while under-powering a complex task produces poor results. A practical starting point:
- Complex tasks: Use Sonnet to build and refine the implementation plan. Use Opus to review and clean up that plan before execution. Once the plan is confirmed, Automode is sufficient to carry it out.
- Simple, well-defined tasks: Automode alone is enough. There is no benefit to involving heavier models when the task and context are already clear.
As a general rule, match the model to the task's complexity. Defaulting to the most powerful model for everything is a common habit that adds cost without improving outcomes.
Building your UI with one chat per feature
One of the most important practical habits in this workflow is to start a new chat in Cursor for each distinct UI element or feature you are working on.
This keeps context windows focused. When you try to build an entire dashboard in a single conversation, the model loses coherence, and the output deteriorates. When you isolate each widget, filter bar, or table to its own chat, the results are precise and easier to iterate on.
The typical flow for each element looks like this:
- Switch to Dev Mode in Figma and copy the component's layout CSS.
- Export all relevant assets (icons, images) from Figma and drag them into the Cursor project.
- Open a new chat, paste the Figma URL, and include the copied CSS and assets in the prompt. Reference the relevant Jira ticket if the MCP is connected.
- Use Plan mode to review the approach, then switch to Agent mode to execute. Review the output in the live preview, then use the Cursor’s element inspector to flag issues and iterate.
Providing the actual assets from Figma is particularly important. Without them, AI tools tend to substitute generic icons or placeholder imagery, which then requires additional cleanup. Giving Cursor the real assets from the start keeps the output faithful to the design.
What changes when the prototype lives in the real codebase
There is a deeper reason to prefer this approach beyond just capability. When you prototype on the actual technology stack that the development team is using, several things happen:
- The prototype behaves exactly as the final product will behave, including real data structures, edge cases, and state management.
- Developers can see a working reference built on the same architecture they are working in, which reduces ambiguity and misinterpretation.
- Client validation becomes far more meaningful. Stakeholders are clicking through something that genuinely reflects the product’s logic, not a simulated approximation.
- Designers gain a much deeper understanding of what is technically feasible, which feeds directly back into the design process and produces better decisions upstream.
In the project this came from, the prototype was built while designs were several sprints ahead of the development team. Starting from the latest front-end build meant layering new interactions on top of what already existed, rather than building in isolation. That alignment between design and implementation is difficult to achieve any other way.
How much do designers actually need to know?
This workflow does require some comfort with unfamiliar territory. Cloning a repository, creating a branch, and running a development server are not tasks most designers do routinely. But none of them requires deep technical expertise. Cursor itself can guide you through most of these steps if needed, and a brief onboarding session with a developer covers the rest.
The honest framing is this: it is a basic-level use of these tools, not an advanced one. The AI does the heavy lifting. What you are providing is design judgment, knowing what the interface should look like, how the interactions should feel, and what the user experience requires. That is not a small thing. It is the reason why the output is worth building.
The bottom line
Figma Make will improve. For certain use cases, it is already a reasonable tool. But for complex, data-driven enterprise interfaces, it is not yet up to the task, and trying to force it to work costs more time than simply learning a more capable approach.
Using Cursor with the real front-end codebase, connected to your design files and project management system, produces prototypes that are functionally indistinguishable from the real product. That has real value: for client alignment, for developer handoff, and for your own understanding of the product you are designing.
If you have been hesitant to try this kind of workflow because it feels too technical, it is worth reconsidering. The tools have lowered the barrier significantly, and product design is better for it. The design judgment you bring to it remains the hardest part, and that is already yours.
FAQs
Integrating AI into design workflows closes the gap between design and development. Designers can build and iterate on working interfaces directly in the codebase, validate interactions with real data, and hand off something functional rather than a static file. The result is faster feedback cycles, fewer misinterpretations, and prototypes that reflect how the product will actually behave — not how it looks in Figma.
A common example is sharing a coded prototype with stakeholders before development begins. Instead of clicking through a static Figma flow, stakeholders interact with a working interface — real data loads, filters respond, error states appear. The team observes where users hesitate or get stuck, and feeds that back into the design process before a single line of production code is written.
Figma works well for static design and simple prototyping. But it struggles when used to build software-grade interfaces with real complexity. AI features like Figma Make break down when interfaces involve dynamic data, multiple pages, or complex components — often stalling or rendering incorrectly. Prototypes are visual approximations, not working implementations, so real functionality such as loading states, error conditions, and live data cannot be properly validated. For enterprise-grade, data-driven interfaces, these limitations matter — they become blockers rather than minor inconveniences.
AI is changing how designers work at every stage of the process. In tools like Figma, AI assists with auto layout, generating initial layouts, and suggesting design system components. In coding environments like Cursor, it helps build interactive components and live prototypes directly in the product's codebase — without requiring designers to write code from scratch.
For example, tools like Claude Code extend these capabilities, allowing designers and developers to implement and iterate on complex UI using natural language. This approach translates design intent into working interfaces more quickly than traditional handoff methods.
The result is a tighter loop between design and development — and prototypes that behave like real products, not simulations.
A coding prototype is a working model of a product built directly in code, rather than in a visual tool like Figma or Sketch. Unlike static mockups, it demonstrates real functionality — interactions, data states, and edge cases behave as they actually will in the final product.
The purpose is to validate a concept early, before full development begins. This makes it far more useful for testing assumptions and gathering feedback than anything a static design tool can surface.
AI-assisted tools like Cursor, for example, help designers create prototypes without writing production-quality code. The AI manages implementation, while the designer provides judgment. For teams that need design and development to stay in sync, coded prototypes keep everyone aligned from the first sprint to the last.
Related Insights
Inconsistencies may occur.
The breadth of knowledge and understanding that ELEKS has within its walls allows us to leverage that expertise to make superior deliverables for our customers. When you work with ELEKS, you are working with the top 1% of the aptitude and engineering excellence of the whole country.
Right from the start, we really liked ELEKS’ commitment and engagement. They came to us with their best people to try to understand our context, our business idea, and developed the first prototype with us. They were very professional and very customer oriented. I think, without ELEKS it probably would not have been possible to have such a successful product in such a short period of time.
ELEKS has been involved in the development of a number of our consumer-facing websites and mobile applications that allow our customers to easily track their shipments, get the information they need as well as stay in touch with us. We’ve appreciated the level of ELEKS’ expertise, responsiveness and attention to details.