VicroCode
Make Code Create Value
VicroCode is a lightweight online platform for publishing, running, sharing, and monetizing code projects. Launch HTML, Python, SQLite, AI agents, management tools, games, and more without server setup.
Please wait while VicroCode loads. You can also explore the AI programming guide
Loading...

AI MARKET GUIDE

Your AI frontend keeps looking like AI because nothing pins it down

A build debrief for the Vue dev stuck in model roulette: stop chasing a stronger model, pin a small design-token contract the model builds against instead.

There's a post going around from a Vue developer who's clearly at the end of their rope. They built a consumer-facing app, but the frontend keeps coming out wrong. They tried feeding screenshots of competitor apps to clone, generating sample HTML to copy from, and every popular "design taste" skill they could find. The mockups looked fine. The moment those turned into real code, the pages came out with that unmistakable AI smell, and worse, the style drifted from page to page. A lot of tokens burned, and the conclusion they landed on was: maybe I need a stronger model. Maybe the one everyone says is great at frontend.

I've been down this exact road, so let me save you the detour. Switching models won't fix this. You'll spend a week evaluating, get a marginally different flavor of inconsistency, and be right back here. The problem isn't the model's taste. It's that nothing is holding the model to a fixed set of decisions between one prompt and the next.

Why every page looks like a different designer made it

When you ask a model to "make a clean, modern settings page," it invents values on the spot. A blue that's `#3B82F6` this time, `#2563EB` next time. Padding that's 16px here, 20px three prompts later. A card radius that wanders between 8 and 12. Each generation is a fresh improvisation, and improvisation is exactly what produces that generic, AI-flavored look, plus the drift you're seeing across pages.

A real design system doesn't work by taste being reapplied every time. It works because the decisions are made once and then referenced. Designers call these design tokens: the small set of named values that everything else is built from. The insight that changes everything here is that a model is perfectly capable of building against tokens. It's just that nobody gave it any. Left without a contract, it defaults to whatever's statistically average, and average is what "AI-looking" means.

Extract a contract, don't chase a vibe

So the move is to stop asking for good design and start handing the model a contract it isn't allowed to deviate from. You don't need to be a designer for this. You need maybe 30 to 50 named values total:

  • **Color**: a primary, a couple of neutrals, a background, a border, one success/one danger. That's often enough.
  • **Spacing scale**: pick a base and step it. 4, 8, 12, 16, 24, 32. Never let the model use anything off-scale.
  • **Radii**: two or three values. Small for inputs, medium for cards, full for pills.
  • **Type ramp**: four or five sizes with their weights and line heights.
  • **Component states**: what a button looks like in default, hover, active, disabled. Same for inputs and cards.

The reason to keep it small is that a small contract is one you can actually hold the line on. If you sketch out 200 tokens you'll never enforce them. Fifty you can.

Make the tokens editable records, not a buried config

Here's where I'd structure it differently from just dropping a JSON file in the repo. Put the tokens in a real table you can edit as data. On VicroCode you can back this with a plain SQLite table, one row per token: a name, a category, a value, and a note about where it's used. The nice part is you can tweak a value in the SQLite editor and treat that table as the canonical record, rather than hunting through code every time you want to nudge the neutral gray a shade darker.

This matters more than it sounds. When your tokens live as editable records, changing your whole app's spacing rhythm is a data edit, not a find-and-replace across forty components. And it gives you one unambiguous place to point the model at.

Build a hosted gallery as the single source of truth

The second piece is a visual one. Generate a single HTML component gallery: every button state, every input, cards, headers, empty states, all rendered on one page using only the token values. Then host it so it has a stable URL you can open anytime. VicroCode lets you run HTML online and publish it, so the gallery becomes a living page rather than a file you forget about.

This gallery is your source of truth in two directions. You look at it to catch anything that feels off, and the model looks at it to see what "a button" concretely means in your system. When something drifts, you fix it in the gallery once. Every page generated afterward inherits the correction instead of re-litigating it.

Rewrite the prompt so it references, never invents

Now the prompts change shape. Instead of "build me a profile page, make it look nice," you give the model the token list and the gallery, and you make the instruction explicit: use only these tokens, reference these exact component definitions, do not introduce new colors, spacing, or radii. If a value you need doesn't exist, ask before creating it.

That last clause is the one that kills the drift. The model's instinct is to fill gaps with invention. When you forbid invention and force it to either use an existing token or flag the gap, the improvisation that produces the AI smell has nowhere to go. Any AI coding assistant that's decent at following instructions can work this way; the leverage comes from the contract, not the model. If you want to go deeper on setting up assistant workflows like this, the material on AI coding is a reasonable starting point.

What this actually buys you

To be straight about the trade-off: this is more upfront setup than typing "make it pretty" and hoping. You spend an afternoon defining tokens and building the gallery before you generate a single feature page. But that afternoon is a one-time cost, and it replaces the open-ended loop of prompt tweaking, model shopping, and token burning that the original poster described. I'd call the consistency payoff reliable in principle, though your specific mileage depends on how disciplined you keep the contract; treat any promise of a fixed result as unverified until you've run it on your own app.

The honest reframe is this. "I have no design sense" is rarely the real blocker for a developer building a functional app. You don't need taste to be consistent. You need a small set of fixed decisions and a mechanism that forces every screen to honor them. The model supplies the labor. The contract supplies the taste, once, so you don't have to keep supplying it and keep getting a different answer.

Stop asking which model is best at frontend. Give whichever model you're already paying for a contract it can't wriggle out of, and the frontend problem mostly stops being a frontend problem.