DEV Community

Tarun Singh
Tarun Singh

Posted on • Originally published at tarunsingh24.Medium

From Figma to Next.js: How I Built a Functional UI Using Kombai

As a frontend developer, I spend so much time just converting Figma designs into components. I’m sure every developer has had this thought: “Why can’t my Figma designs just turn into React code directly?”

I know, there have been tools and Figma plugins claiming this for years. These “design-to-code” tools promise to save us hours. But, most of the time, they spit out code that’s only good for a demo. It’s not code you’d ever want to merge into a production app.

This all changed after I tried Kombai AI. It honestly felt different from the other AI frontend tools I’ve used (like Locofy.ai or even the newer LLMs). It didn’t promise me magic. Instead, it felt like it was actually trying to solve the problem in a way that respects both the design and the code.

In this post, I’ll show you how I used Kombai to go from a Figma file to a real Figma to Next.js workflow, what worked, what didn’t, and what it all means for us frontend devs.

The Pain of Developers to Convert Figma to Code

If you’re a frontend dev, you know this story all too well. You get a beautiful, pixel-perfect Figma file from the design team. Everything looks clean. But when you sit down to convert the design to code, you spend hours figuring out element spacing, typography, colors, responsiveness, and component hierarchy.

It’s not simply copying and pasting your design tokens, but translating the visual intention into code logic that creates the time loss.

Designers think in frames, layers, and constraints. Developers think in components, props, pages, and layouts. And therefore, we see a gap between the two, and it’s not simply a communication problem; it’s a structural dissonance.

My Setup: Real-World Workflow, Not a Demo

To make this a real test, I didn’t want to use a simple to-do app or a simple landing page. I decided to test Kombai AI inside a real project I’m already working on.

The Project: I’m building a simple task-board dashboard. It’s my personal sandbox for testing new tech, so it’s perfect for this.

The Stack: It’s a modern, real-world stack. No weird or obscure libraries. This is the stuff most of us are working on every day:

  • Next.js 16 (using the App Router)
  • TypeScript
  • Tailwind CSS

The Test Case: My goal was simple but specific. I had a component in Figma called TaskCard. It’s not complex, but it’s not trivial. It has an icon, a title, and multiple more items.

My test wasn’t just “Can I get the code for this?” My test was:

  1. Can Kombai generate a usable React component for this card?
  2. Can I put this component in my /components folder?
  3. Can I then go to my page.tsx, import the component, and pass props to it from a JSON array?

That’s the test. Not just copying, but integrating. If it could do that, it would be a game-changer.

Step-by-Step: How I went from Figma to Next.js

My Next.js “Task Board” project UI was almost done, but I had been putting off building the main TaskCard component. It was the perfect test.

Here’s exactly what I did, following the official workflow.

Step 1: Connecting and Configuring

Kombai AI runs as an IDE extension. You can install in VS Code, Cursor, Windsurf, or Trae. I installed it in VS Code. This already felt more developer-centric. It lives where I live.

Homepage of the Kombai AI website

Next, it asked me to Sign In. Once you’re signed in, you can see it available in the Primary Side Bar of VS Code.

Step 2: Add Figma and Prompt

This is where it gets cool. In the Kombai chat box, I typed @figma (as the docs suggested) and pasted the public link to my “Task Boards” Figma file.

Kombai extension inside VS Code, showing the ‘Enter the link to your Figma frame’ input box

After I confirmed the link, Kombai’s input box was ready for my prompt. This answers the question: yes, you should add a prompt. I didn’t just give it the file; I gave it instructions. I wrote:

“Using this file, please build the TaskCard component for my ‘To Do Tasks’ column. It needs to be a reusable React component with props for the title, task ID, and tags.”

Before finally moving to create the component, I also configured my tech stack in the tool. After finalizing that, I clicked the Send button.

Kombai interface in VS Code showing the configured tech stack

Step 3: Review the “Editable Plan” (The “Wow” Moment)

This was the part that really caught my attention. Before writing a single line of code, Kombai presented me with a detailed Editable Plan.

It said something like:

“I’ll create a reusable TaskCard component based on the Figma design. First, let me examine the existing code structure and then build the component with proper sub-components for avatars, tags, and footer elements.”

Step 4: The Code Review (The 90% Solution)

Kombai took about 40–50 seconds, and then a new file, TaskCard.tsx, appeared in my /components folder.

//app/components/TaskCard.tsx
import type { ReactNode } from "react";
import CheckIcon from "./icons/CheckIcon";
import FileIcon from "./icons/FileIcon";
import MessageIcon from "./icons/MessageIcon";
import PlusIcon from "./icons/PlusIcon";
export interface TaskCardProps {
  title: string;
  taskId: string;
  tags: Array<{
    label: string;
    variant: "design" | "development" | "backlog" | "todo" | "inprocess" | "done" | "verify" | "project";
  }>;
  checkCount?: number;
  fileCount?: number;
  messageCount?: number;
  avatars?: Array<{
    src: string;
    alt: string;
  }>;
  additionalAvatarCount?: number;
  showFooter?: boolean;
}
export default function TaskCard({
  title,
  taskId,
  tags,
  checkCount,
  fileCount = 2,
  messageCount = 4,
  avatars = [],
  additionalAvatarCount = 0,
  showFooter = true,
}: TaskCardProps) {
  return (
    <div className="bg-(--card-bg) rounded-lg border border-(--card-border) p-4 shadow-sm hover:shadow-md transition-shadow">
      {/* Header */}
      <div className="flex items-start justify-between gap-3 mb-3">
        <h4 className="task-title flex-1">{title}</h4>
        {checkCount !== undefined && (
          <div className="flex items-center gap-2 shrink-0">
            <CheckIcon width={13} height={17} color="var(--icon-check)" />
            <span className="task-count" style={{ color: "#17a5e6" }}>
              {checkCount}
            </span>
          </div>
        )}
      </div>
      {/* Tags */}
      <div className="flex items-center gap-2 mb-3 flex-wrap">
        <TaskTag label={taskId} variant="id" />
        {tags.map((tag, index) => (
          <TaskTag key={index} label={tag.label} variant={tag.variant} />
        ))}
      </div>
      {/* Footer */}
      {showFooter && (
        <div className="flex items-center justify-between gap-3">
          <AvatarGroup
            avatars={avatars}
            additionalCount={additionalAvatarCount}
          />
          <div className="flex items-center gap-2">
            <IconWithCount
              icon={<FileIcon width={13} height={17} color="var(--icon-file)" />}
              count={fileCount}
              countColor="#9333ea"
            />
            <IconWithCount
              icon={<MessageIcon width={17} height={17} color="var(--icon-message)" />}
              count={messageCount}
              countColor="#d97706"
            />
          </div>
        </div>
      )}
    </div>
  );
}
// Sub-components
interface TaskTagProps {
  label: string;
  variant: "id" | "design" | "development" | "backlog" | "todo" | "inprocess" | "done" | "verify" | "project";
}
function TaskTag({ label, variant }: TaskTagProps) {
  const variantStyles: Record<typeof variant, { text: string; bg: string }> = {
    id: { text: "text-(--text-secondary)", bg: "bg-gray-100" },
    design: { text: "text-(--tag-design)", bg: "bg-blue-50" },
    development: { text: "text-(--tag-development)", bg: "bg-pink-50" },
    backlog: { text: "text-(--tag-backlog)", bg: "bg-yellow-50" },
    todo: { text: "text-(--tag-todo)", bg: "bg-pink-50" },
    inprocess: { text: "text-(--tag-inprocess)", bg: "bg-purple-50" },
    done: { text: "text-(--tag-done)", bg: "bg-green-50" },
    verify: { text: "text-(--tag-verify)", bg: "bg-purple-50" },
    project: { text: "text-(--text-secondary)", bg: "bg-gray-100" },
  };
  const styles = variantStyles[variant];
  return (
    <span className={`task-tag ${styles.text} ${styles.bg} px-2 py-1 rounded-full`}>
      {label}
    </span>
  );
}
interface AvatarGroupProps {
  avatars: Array<{
    src: string;
    alt: string;
  }>;
  additionalCount?: number;
}
function AvatarGroup({ avatars, additionalCount = 0 }: AvatarGroupProps) {
  return (
    <div className="flex items-center gap-2">
      <div className="flex -space-x-2">
        {avatars.map((avatar, index) => (
          <img
            key={index}
            src={avatar.src}
            alt={avatar.alt}
            className="w-8 h-8 rounded-full border-2 border-white object-cover"
          />
        ))}
        {additionalCount > 0 && (
          <div className="w-8 h-8 rounded-full border-2 border-white bg-gray-100 flex items-center justify-center">
            <span className="avatar-count">+{additionalCount}</span>
          </div>
        )}
      </div>
      <button className="shrink-0" aria-label="Add member">
        <PlusIcon width={13} height={13} color="var(--icon-plus)" />
      </button>
    </div>
  );
}
interface IconWithCountProps {
  icon: ReactNode;
  count: number;
  countColor?: string;
}
function IconWithCount({ icon, count, countColor }: IconWithCountProps) {
  return (
    <div className="flex items-center gap-2">
      {icon}
      <span className="task-count" style={{ color: countColor }}>
        {count}
      </span>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

This was 90% perfect. It used clean, standard Tailwind classes. It correctly created and mapped the tags prop.

It wasn’t 100% perfect, of course. For example, I noticed it generated bg-(--card-bg) for the background. This is a common AI mistake, as the correct syntax is bg-[var(--card-bg)]. This was a 5-second fix and is exactly the kind of '10% fix' I'm happy to make.

Step 5: Preview and Follow-up
As soon as Kombai finished generating the code, my Next.js dev server (which was already running) auto-reloaded. I just clicked over to my browser tab.

It worked. Perfectly.

The final, rendered Next.js application running in the browser, showing the new TaskCard components

Here’s the UI of the TaskCard component in the figma file I provided to build using Kombai:

Sample task board cards from the original Figma design

The docs also mentioned I could use the Start Preview button to use the “Kombai Browser” to tag DOM elements and ask for changes, but I didn’t even need to. My card was there, rendered with my real data (integrated automactially by the Kombai AI in my page.tsx file.

This whole process, which would have easily taken me an hour or more of tedious pixel-massaging, was done in five minutes.

Why Kombai Felt Different than Others?

So, why did this feel so different? Simple. I’m used to tools like Locofy or Anima that just “export” messy code I have to delete. They feel like a black box.

Kombai, on the other hand, lives right in my VS Code or Cursor. It understood my Next.js and Tailwind stack. It didn’t give me junk but gave me a clean, production-ready component with real props. It’s the first tool that feels like it was actually built for a developer, not just at one.

What did I learn? (and What’s Next)

My takeaway is that we are now in new territory. These tools are not intended to deliver 100% automation. I want a tool to assist me in data-fetching logic or complex state management. That’s my job, and that’s the fun work.

I never want to manually go from Figma’s 16px margin to m-4 again. That is boring, repetitive, low-value work.

Kombai AI is the first tool that I’ve used that truly automates the boring part. It gave me a UI with a 90% solution where I could use my time on the 10% that matters, fixing minor issues, wiring it up, managing state, and shipping.

It allows me to focus on being an engineer instead of a pixel-to-code translator. I’m focused on architecture, data flow, and performance. This is why I think using something like Kombai is becoming mandatory. It is not about replacing developers; it is about upgrading them.

Wrap Up

Developing production-level UIs from Figma has always been a bottleneck. It’s a slow, manual grind that burns time, budget, and developer morale.

But the new generation of AI frontend tools is finally changing that. We’re moving from “this is too messy to use” to “this is a 90% head start.”

For any developer, whether you’re a solo builder or on a fast-paced team, this is a massive speed boost. We can build and iterate faster. We can spend more time on complex problems and less time on repetitive ones. Stop spending your days in that repetitive loop.

Give a tool like this a try on your real Figma to Next.js project. Go try it. I’m curious to hear if your experience is the same as mine.

Top comments (0)