Guide · how-to
how to feed a real design system to Codex, v0, and Bolt
Prompt v0, Bolt, or Codex for a landing page and you get the same page back: a purple-to-blue gradient, three feature cards, Inter headlines, a centered hero. It is the statistical average of every UI these models were trained on, and it shows up no matter which tool you use, because you handed all three the same thing, which is almost nothing. The fix is not a better adjective. It is real design context: your actual tokens and a real section structure, delivered in the specific way each tool can read. That last part matters, because these three tools do not accept context the same way, and most guides blur them together.
the three tools are not interchangeable
Here is the honest map of what each one supports today, before we talk about how uiscanner fits in.
| Tool | How it takes design context | Native design-system feature |
|---|---|---|
| Codex | Reads the repo plus AGENTS.md, screenshots, and MCP servers you configure | No importer, it reads your repo's existing primitives |
| v0 | shadcn registry (registry.json, tokens.css), tailwind config plus globals.css, project Knowledge, MCP | Registry built on the shadcn CSS-variables standard |
| Bolt | A compiled design system synced from your own sources | Custom systems on a paid Team plan; example systems for everyone |
That table is the whole reason this post exists. Codex lives in your repo, so it wants context as files and tools. v0 is coupled to shadcn/ui and Tailwind, so it wants tokens in the shadcn variable format. Bolt has its own design-system product that compiles from a component library or a design-system website. Feed all three the same paragraph of prose and only the vaguest layer lands.
where uiscanner comes in
uiscanner takes any public URL and returns a design teardown: tokens (colors, fonts, type scale, radii, spacing, shadows, motion), a section-by-section structure, and a Claude-tailored build prompt to recreate the look. It reads the rendered page with vision plus the DOM, so it catches what a code scraper misses: the real primary button rather than the first one in source, whether the hero is centered or split, and which imagery is decorative (with prompts to recreate it as originals). It describes and tokenizes a page and never copies or re-hosts the original asset bytes, so you rebuild in your own stack from the tokens and structure, not from someone's literal files.
That output is exactly the shape each of these tools is missing. Only the delivery changes: a live MCP tool for Codex, a compact pasted reference for v0 and Bolt. Let us do all three.
Codex: wire it in over MCP
Codex reads MCP servers, and uiscanner is one. This is the tightest integration of the three because the agent can call the teardown mid-build instead of you pasting anything. One line registers it (the same server works for Claude Code and Cursor too):
claude mcp add uiscanner -- npx -y uiscanner-mcp@latest
Once registered, the agent gets five tools it can call while it works:
| Tool | What it does |
|---|---|
ui_probe | Cheap preflight on a URL, spends no scan |
ui_teardown | Scans a page, returns tokens, structure, and a build prompt plus a shareable link |
get_teardown | Re-fetches a finished teardown by id or link |
retarget_teardown | Re-tailors the prompt to another archetype without re-scanning |
whoami | Reports your plan and scans remaining |
OpenAI's own frontend guidance for Codex says to tell it "which primitives to reuse, where your tokens live, and what the repo considers canonical," and to hand it concrete visual references. A teardown is precisely that, delivered as a tool call rather than a screenshot you have to describe. A working instruction reads like this:
Use the uiscanner MCP: run ui_teardown on stripe.com with target "landing".
Build our hero from the returned tokens, section structure, and build prompt.
Reuse our existing primitives; borrow the type scale, spacing, and motion, keep our copy.
Codex also reads an AGENTS.md file for project rules, the natural place to pin one instruction: "for any new screen, run a uiscanner teardown of an approved reference first, then build from its tokens." Then the design step is part of how the repo works, not something you remember. There is no hosted endpoint, by the way: the server runs locally over stdio, and https://uiscanner.com/mcp is documentation, not a remote MCP URL.
v0: paste the teardown into Knowledge
v0 has real design-system support, but it is shadcn-shaped. Per the v0 docs, it reads a registry (registry.json, a tokens.css following the shadcn CSS-variables standard), your tailwind config, and globals.css. If you maintain a shadcn registry, that is the cleanest path and you should use it. But most people reaching for v0 do not have a registry yet, and that is where a teardown shortcuts the work.
v0 lets you set project Context and Knowledge in plain language. Instead of writing "glassmorphism with pastel gradients" and hoping, run a teardown of a page whose language you want and paste the structured result in. You are giving v0 real hex values, a real type scale, and a real section order rather than a vibe. Because the tokens map directly onto shadcn's CSS variables, they translate cleanly: drop the color roles into tokens.css and the type and spacing decisions into your tailwind config, and v0 generates against your system instead of its default. The CLI produces the same teardown if you would rather grab it outside an agent:
npx -y uiscanner-mcp@latest scan stripe.com --target landing
The one thing to be accurate about: v0 is coupled to shadcn/ui and Tailwind. A teardown gives it better raw material, but you are still building in that stack, which is a fit, not a workaround, for most React work.
Bolt: seed the prompt, or feed the design-system product
Bolt has its own design-system feature. Per Bolt's docs, it compiles a system from your own sources (a component library, a design-system website) covering colors, typography, spacing, and component styles, and custom systems live on a paid Team plan. If you have that, use it. Without a maintained system, a teardown is the fastest way to stop generic output: paste the tokens and section structure into your build prompt so Bolt generates from concrete values instead of guessing. Bolt supports frameworks beyond React, and the tokens-and-structure format travels well here because it is stack-agnostic data, not shadcn-specific code.
why this beats pasting raw HTML
The usual advice, captured well by the Design Systems Collective writeup, is to feed these tools real code rather than prose. The instinct is right, the mechanics are rough. Pasting raw HTML and CSS dumps thousands of tokens of framework noise and utility-class soup into context, most of it irrelevant, and it means building on someone's literal bytes. A teardown is the same signal without the noise: structured tokens and a section map cost a fraction of the context, and because uiscanner tokenizes rather than copies, it is clean footing to build a product on.
A loop that holds up across all three tools:
- Pick two or three real pages whose design language you admire. Browse example teardowns to see the output shape first.
- Run
ui_probeto confirm a URL is scannable, thenui_teardownon the ones worth learning from. - Deliver it the way the tool reads: MCP for Codex, Knowledge or
tokens.cssfor v0, the build prompt for Bolt. - Keep your own copy and brand. Borrow the system, not the words. If the same reference should drive a dashboard next, call
retarget_teardown(targets:landing,dashboard,marketing,ecommerce,portfolio,mobile,general) instead of scanning again.
Every scan returns an id and a shareable uiscanner.com/t/<id> link, so a reference you pull once is reusable across a whole feature. If you want to see a finished teardown before wiring anything up, read the Stripe teardown or the v0 teardown, then connect the MCP server with the one-liner above.
The free plan includes 5 scans per rolling 30 days, and paid plans (Indie at 100 scans, Studio at 400) share one quota across the web app, MCP, and CLI. Point each tool at a real reference in the format it actually reads, and the generic look goes away, because you finally told the model what "good" means.