Build a SaaS app with Claude Code and a design system
A working setup for building product screens with Claude Code on Prodular UI: install the kit, connect the MCP server, write the rules once, ask for outcomes and check what the agent wrote.
By Prodular · Published
Claude Code can write a good screen from one prompt. The trouble starts at the tenth screen. Each prompt is a new chance to pick a different gray, a new card style or a button that almost matches the last one. The fix is not a longer prompt. It is a design system the agent can find, install and check itself against.
This guide sets that up with Prodular UI. The same steps work with any design system that publishes a shadcn registry and rules an agent can read.
What you end up with
- The kit installed in your repo as source code you own.
- Claude Code connected to the Prodular UI MCP server, so it can search the kit, read how each component should be used, install what is missing and check what it wrote.
- A short
CLAUDE.mdsection, so the agent reaches for the kit by default.
1. Start from a React project with Tailwind CSS v4
Next.js is the shortest path, because the CLI wires fonts and the theme into the layout for you. Other React setups work too: init prints the two steps to finish by hand. The CLI needs Node 20.18 or newer.
npx create-next-app@latest relaycd relaynpx prodular-ui initinit sets up shadcn with Base UI if the project does not have it yet, adds the Prodular registry to components.json, installs the tokens and the stylesheet, and sets data-theme on the root element. Pick another theme any time with npx prodular-ui theme iris.
2. Connect Claude Code
npx prodular-ui mcp init --client claudeThis adds the server to the project's .mcp.json and keeps any servers you already have. If you prefer the Claude Code command line:
claude mcp add prodular-ui -- npx -y prodular-ui@latest mcpRestart Claude Code. It now sees six tools: get_guidelines, search_items, get_item, get_project, add_items and check_ui. The server runs on your machine and does not send your code anywhere. It downloads the component index from ui.prodular.co and falls back to a copy inside the package when you are offline.
3. Write the rules once
Agents decide when to call a tool. Put the default in writing so you do not repeat it in every prompt. Add this to CLAUDE.md (or AGENTS.md for other agents):
## UI
This project uses Prodular UI. Before writing UI:
- Read https://ui.prodular.co/llms.txt and the page of every component you use.- Install components with `npx shadcn@latest add @prodular/<name>`. Do not hand-roll a component that exists.- Use semantic tokens only (bg-card, text-muted-foreground, border-border). No raw colors.- Mark anything a model produced with AiMark, Message or Reasoning.- Irreversible or external actions taken by an agent go through Approval.- One container level. Separate content inside cards with dividers, not nested boxes.4. Ask for outcomes, not layouts
Describe what the screen is for. Let the agent find the parts.
Build a billing settings page with the current plan, usage and invoices.
The agent calls search_items first. This is what the server returns for that request, trimmed to the names:
[ { "name": "usage-billing", "kind": "block", "tier": "pro" }, { "name": "settings", "kind": "block", "tier": "pro" }, { "name": "plan-picker", "kind": "component", "tier": "pro" }, { "name": "usage-meter", "kind": "component", "tier": "pro" }, { "name": "settings-nav", "kind": "component", "tier": "free" }]Full screens come first when one fits, so the agent starts from a finished billing page instead of assembling one. For each part it then calls get_item, which returns when to use the component and when not, its props, a minimal example and rules written for agents. For Approval, one of those rules reads:
Route every irreversible, external or financial action through an Approval and wait for an explicit approve event before executing it. Never execute on render, on timeout or on dismiss.
That is the kind of judgment an agent gets wrong without being told, and the kind a human reviewer misses in a long diff.
5. Install and compose
add_items installs components and blocks with everything they depend on. Blocks land in app/<slug>/ as ordinary files. Edit them like any other code: the data, the copy, the routes.
Free components install without a license. Pro components and blocks need one: run npx prodular-ui login once and the server uses the same saved token. Without it the agent gets a clear answer instead of an error, and the rules tell it to offer the closest free item.
6. Check what it wrote
Ask the agent to run check_ui on the files it changed, or make it part of the rules. It reports raw colors instead of tokens, hand-rolled buttons, inputs and tables the kit already has, cards inside cards, icon buttons without a label, generic button labels and model output that is not marked as AI.
Then review what a check cannot see:
- States. Does the screen handle empty, loading and error? Prodular UI's application blocks ship with their states; screens the agent writes from scratch often do not.
- Copy. Are actions verbs with their object, such as Export CSV or Approve refund?
- Data. Blocks ship with sample data for a fictional product. Replace it with your own before you ship.
What this does not solve
A design system makes screens consistent. It does not decide what your product should do, which data matters or how a workflow should behave. Those are still your calls, and the agent still needs a reviewer.
If your team already has a mature design system, connect that instead. The shadcn MCP server works with any shadcn-compatible registry, and the same CLAUDE.md approach applies.
Without MCP
Some setups cannot run an MCP server. The same knowledge is published as plain text: llms.txt is a short index with the rules, and llms-full.txt has every component's guidance, props and example. Point the agent at them in CLAUDE.md.
Next: How to keep AI-generated React interfaces consistent, or set up the MCP server for Cursor and VS Code.