New May 3, 2026

Cursor for UI Work

More Front-end Bloggers All from Kitty Giraudel View Cursor for UI Work on kittygiraudel.com

The setup

A while ago, I received the board game called Par Odin!. It’s a little solo puzzle game. You have to divide a draft of 7–9 units into 2 armies of equal strength. Each unit has a value, either static or dynamic, depending on the unit and its surrounding allies.

While the game is fun, I was more interested in writing an automated solution for all 50 challenges from the rulebook. After all, it’s essentially a basic math problem that can be brute-forced. So I wrote a solver in TypeScript.

Just for fun, I also wanted to build a little UI so you can make your own drafts, and run the solver on them. It was also a good opportunity to see what Cursor is like for UI work, as someone who has done frontend for almost 15 years. You can try the game for yourself here.

Screenshot of the Par Odin! solver interface in Chrome
The browser UI for the Par Odin! solver

Getting it off the ground

My initial prompt was intentionally vague:

How about we build a little UI for that game? Maybe you can create your draft, and then solve it?

After exploring all 7 files, Cursor followed up with a few interesting questions for which it provided helpful possible answers:

After that, it worked on it for a few minutes and spit out a relatively clean dashboard for the game. It took care of the Vite setup, the package.json script, the React implementation, and created the necessary component with all the core logic wiring the existing solver.

It’s worth pointing out that it simply didn’t work to begin with. I had to ask it whether it even attempted to run it, because there were some TypeScript errors, and the browser couldn’t load anything. But after being prompted, it did fix the issues.

Besides this hiccup, the initial bootstrapping was good, even though it stuffed everything in a 500 lines long App.tsx component, but I guess that’s on me for not asking it to create smaller components. I did ultimately instruct it to have each component in a separate folder within its own styles, and it delivered (faster than I could have, may I add).

And even in spite of that, it set up the whole thing so much faster than I could have ever had. Just the initial React + Vite setup would have taken me 10–15 minutes.

Looking into the code

While getting it off the ground was fast and relatively easy, I faced two significant problems:

Creativity is inherently subjective

I wasn’t overly surprised by the fact that Cursor couldn’t come up with something engaging and exciting for a small game interface. First of all, because I didn’t explicitly requested it to do so, but also because it’s ultimately trained on a certain type of software, and is good at reproducing what exists. And what exists is a million dashboards all looking more or less the same.

I don’t think it would be fair of me to expect creativity and art-direction from Cursor. After all, it did come up with something clean and usable in the first place, so the rest is up to me I suppose.

After the first pass, I had an idea of how I wanted it to look and gave it some guidance to get there. It wasn’t incredibly fruitful and required several back-and-forths to get somewhere decent, which I guess is the problem with having a coworker that can neither see nor comprehend the design vision.

Code quality is a mixed bag

More surprising though is that the code was nothing to write home about. In no particular order, here are the things I noticed:

So what?

The result is that I had to go over so much of the code to improve or downright fix it, sometimes with Cursor’s help as well (which was doubly infuriating I must say). It took a lot of time, and I genuinely wonder whether I wouldn’t have been faster on my own.

Now, this was admittedly the wrong approach. Instead of leaving it to its own device to build a whole interface, I should have given it narrow and precise tasks such as “Create a reusable Button component that can be themed” or “Build the core application logic in a testable hook using the existing solver.” It’s a good learning for next time.

What I did like is that it did a bunch of bootstrapping for me. With a bit more guidance on what really matters (such as component reusability and logic encapsulation), it would have probably nailed it out of the park and got most of the way there.

Scroll to top