Why AI-built apps all look the same, and how to fix it
AI coding agents reach for the same defaults on every project. Where the generic look comes from, why prompts don't fix it, and what does.
The Wuizard team4 min read
On this page
Open a handful of apps built mostly by AI coding agents and a family resemblance shows up fast. A centred hero with a soft gradient behind it. Cards with the same medium radius and the same faint shadow. A blue or purple accent. Every element fading in over the same fraction of a second. None of it is bad. It's just the same, and people notice.
This isn't because the agents are poor at UI. They're very good at writing it. The sameness comes from what they're given to work with, which on most projects is nothing at all.
Where the generic look comes from#
When an agent builds a screen without guidance, it makes hundreds of small choices: which grey for borders, how round the corners are, how long a transition takes, what a button does when pressed. With nothing to go on, each choice lands on the most common answer: the framework's default palette, the spacing most tutorials use, the fade everyone writes.
Each default is reasonable. Stack a few hundred of them and you get an app that looks like the average of every app, because in a real sense it is.
Why better prompts don't fix it#
The natural response is to describe the style you want. That helps for a screen or two, then runs into three problems.
- Adjectives are ambiguous. "Clean", "premium" and "playful" each describe thousands of possible designs. The agent picks one, and next time it may pick another.
- Context resets. The careful instructions from last week's conversation aren't in this week's. Unless you paste them every time, the agent starts from its defaults again.
- The task crowds out the style. When you ask for a billing page, most of the agent's attention goes to the billing logic. A paragraph about tone is easy to underweight.
The result is drift. Each screen is fine on its own, but the settings page and the billing page don't quite belong to the same product.
What fixes it: decisions the agent can look up#
Design teams solved this long ago with design systems: decisions made once, written down and reused everywhere. Your colours are a fixed list. Corners are one of three radii. Every modal opens the same way. Nobody re-decides any of it per screen.
Agents need the same thing, in a form they can read when they need it, rather than remember from a prompt. A lookup is reliable in a way memory isn't. If the agent can ask for the primary button and get back the exact component, it has no reason to write a new one.
Tokens alone get you halfway#
A common first step is a tokens file: your colours, fonts and spacing as CSS variables. It helps, and it's the right foundation. But a lot of what makes an app feel generic isn't in the tokens.
It's in behaviour. How a button responds to a press. Whether a modal scales up, slides in or just appears. How lists stagger, how pages hand over to each other, what a loading state looks like. Two apps with identical colours can feel completely different because of motion alone, and an agent working only from tokens will still write the default fade for all of it.
So a system an agent can follow needs both: the values, and the actual components that use them, including how they move. That means choosing a page transition and a toast once and having every screen use them, not describing them.
Make it checkable#
Even with a system in place, agents slip: a hard-coded hex value here, a hand-written button there. The fix is the same as for people: review. A quick check before a screen is accepted, comparing the new code with the system, catches most of it while it's still cheap to change.
How Wuizard approaches it#
Wuizard is built around this idea. Your design system lives in a sheet: foundations (colour, type, radius, spacing, shadows and a motion spring), slots that each hold one chosen component, and short rules. You fill the slots from a live library of components, animations and transitions, all of which read your foundations. What goes into a design sheet covers each part.
Your agent connects over MCP. Before it builds UI it calls get_sheet; for each component it calls get_slot and gets the exact code with your values filled in. When it's done, check_ui reviews what it wrote against the sheet. The MCP setup guide shows how to connect the common agents, and how a coding agent reads your design system follows one screen from prompt to code.
There are other reasonable ways to get here, from a hand-written rules file to a component library in your repo. Component libraries vs a design sheet compares them fairly.
A quick test for your own app#
Whatever tools you use, these questions show how much of your app's look is yours and how much is the agent's defaults:
- Is every colour in the code from a list you chose?
- Do all primary buttons look and behave the same on every screen?
- Does every modal open and close the same way?
- Is there one motion style, or a different duration in every file?
- Could you change your accent colour in one place and see it everywhere?
Every "no" is a decision the agent is still making for you. Make it once, put it where the agent can look it up, and the generic look goes with it.
In the library