AI UI Generation
When to Use
Building or consuming AI-generated UI: prompt-to-component scaffolding, JSON/schema-driven rendering, server-driven UI, or a chat surface that renders components instead of prose. Also when reviewing model-generated markup before it ships.
Stack
React 19 · TypeScript strict · Zod for boundary validation · Tailwind v4
Core Rules
- Generated code is untrusted input. It passes the same gate as hand-written code — no exemptions, ever.
- Never render model output as raw HTML. No
dangerouslySetInnerHTML on generated strings; that is the injection surface.
- Constrain by registry, not by prompt. For generative interfaces, expose a closed set of typed components the model selects from. The registry is the safety boundary — a prompt is not.
- Validate props at the boundary with a schema, before render. Failure renders the component's error state, never a blank.
- Unknown component → documented fallback. Never improvise markup for a name you don't recognise.
- Keep the registry small. Every entry is misuse surface, and selection accuracy degrades as it grows.
- Rewrite colours to OKLCH on arrival — generators emit hex by default.
- Add what generators always omit: loading/empty/error states,
prefers-reduced-motion, aria-label on icon-only controls, real prop interfaces.
- Put the tokens in the prompt. Given a token, a model uses it; given "our brand colour", it invents indigo.
- Constraints as bans beat adjectives. "No gradients, no card grid, OKLCH only, TS strict" shapes output far better than "modern and clean".
Patterns
- Prompt → component — first-draft scaffold, always rewritten. Never a final artifact.
- JSON → UI — schema-validated tree rendered through owned components.
- Component registry — closed, typed, Zod-validated; the model selects and fills props, never emits markup.
- AI design review — model critiques against the anti-slop wall and
core/validate-checklist.md rather than generating.
Reference Index
Load only for the specific task:
| Task |
Load |
| Generation shapes, registry pattern, guardrails, prompt shape, when to avoid |
references/generation-patterns.md |
| Registry/catalog mechanics, Zod-as-tool-definitions, streamed spec shape, partial-prop rendering |
references/generative-ui-runtimes.md |
| The constraint list generated output must satisfy |
core/validate-checklist.md |
| Prop/schema design for registered components |
core/component-api.md |
| Behavioural discipline when accepting generated work |
core/agent-behavior.md |
Constraints
No dangerouslySetInnerHTML on model output · schema validation at every boundary · OKLCH tokens, no raw hex (COL-04) · TypeScript strict with real prop interfaces (TS-01-AST) · four states present · prefers-reduced-motion handled (MOTION-01) · axe-clean before ship. Generated output that cannot pass the parser gate is fixed at the prompt or the registry — never exempted.
1---2name: ai-ui-generation3description: Prompt-to-UI, JSON-to-UI and generative-interface patterns — component registries, schema validation, and the guardrails generated markup must pass. Use when building or consuming AI-generated UI — prompt-to-component scaffolding, schema-driven or server-driven rendering, a chat surface that renders components rather than prose — or when reviewing model-generated markup before it ships.4---56# AI UI Generation78## When to Use9Building or consuming AI-generated UI: prompt-to-component scaffolding, JSON/schema-driven rendering, server-driven UI, or a chat surface that renders components instead of prose. Also when reviewing model-generated markup before it ships.1011## Stack12React 19 · TypeScript strict · Zod for boundary validation · Tailwind v41314## Core Rules151. **Generated code is untrusted input.** It passes the same gate as hand-written code — no exemptions, ever.162. **Never render model output as raw HTML.** No `dangerouslySetInnerHTML` on generated strings; that is the injection surface.173. **Constrain by registry, not by prompt.** For generative interfaces, expose a closed set of typed components the model selects from. The registry is the safety boundary — a prompt is not.184. **Validate props at the boundary with a schema**, before render. Failure renders the component's error state, never a blank.195. **Unknown component → documented fallback.** Never improvise markup for a name you don't recognise.206. **Keep the registry small.** Every entry is misuse surface, and selection accuracy degrades as it grows.217. **Rewrite colours to OKLCH on arrival** — generators emit hex by default.228. **Add what generators always omit:** loading/empty/error states, `prefers-reduced-motion`, `aria-label` on icon-only controls, real prop interfaces.239. **Put the tokens in the prompt.** Given a token, a model uses it; given "our brand colour", it invents indigo.2410. **Constraints as bans beat adjectives.** "No gradients, no card grid, OKLCH only, TS strict" shapes output far better than "modern and clean".2526## Patterns27- **Prompt → component** — first-draft scaffold, always rewritten. Never a final artifact.28- **JSON → UI** — schema-validated tree rendered through owned components.29- **Component registry** — closed, typed, Zod-validated; the model selects and fills props, never emits markup.30- **AI design review** — model critiques against the anti-slop wall and `core/validate-checklist.md` rather than generating.3132## Reference Index33Load only for the specific task:3435| Task | Load |36|---|---|37| Generation shapes, registry pattern, guardrails, prompt shape, when to avoid | `references/generation-patterns.md` |38| Registry/catalog mechanics, Zod-as-tool-definitions, streamed spec shape, partial-prop rendering | `references/generative-ui-runtimes.md` |39| The constraint list generated output must satisfy | `core/validate-checklist.md` |40| Prop/schema design for registered components | `core/component-api.md` |41| Behavioural discipline when accepting generated work | `core/agent-behavior.md` |4243## Constraints44No `dangerouslySetInnerHTML` on model output · schema validation at every boundary · OKLCH tokens, no raw hex (`COL-04`) · TypeScript strict with real prop interfaces (`TS-01-AST`) · four states present · `prefers-reduced-motion` handled (`MOTION-01`) · axe-clean before ship. Generated output that cannot pass the parser gate is fixed at the prompt or the registry — never exempted.