Ai Ui Generation
AI-assisted UI generation patterns for json-render, v0.app, Google Stitch, Bolt Cloud, and Cursor workflows. Covers prompt engineering for component and full-stack app generation, review checklists for AI-generated code, design token injection, refactoring for design system conformance, and CI gates for quality assurance. Use when generating UI components with AI tools, rendering multi-surface MCP visual output, reviewing AI-generated code, or integrating AI output into design systems.
Auto-activated โ this skill loads automatically when Claude detects matching context.
AI UI Generation
Patterns for generating, reviewing, and integrating UI components produced by AI tools (json-render, v0.app, Google Stitch, Bolt Cloud, Cursor). json-render is the first choice for multi-surface, MCP visual output, and type-safe catalog workflows. AI-generated UI is 80% boilerplate, 20% custom โ the human reviews, refactors, and owns the output. These rules ensure AI output meets design system, accessibility, and quality standards before shipping.
Tool landscape as of 2026-04:
- v0.dev โ v0.app (Jan 2026 rebrand) โ expanded from component scaffolding to full-stack app generation with shipping targets (Vercel, Cloudflare, Railway). v0.app MCP server (
@vercel/v0-mcp) exposes generation as an MCP tool, so agents can call it programmatically.- Google Stitch โ design-first generation via
stitch.withgoogle.com/docs/mcp. Produces multi-screen apps (up to 5 interconnected screens) with React/HTML + PNG. Strong when input is a screenshot, URL, or DESIGN.md file.- Bolt Cloud (StackBlitz, 2026) โ Bolt now runs the dev environment in the cloud (no local WebContainer). Integrates with GitHub and supports persistent databases. Best for full-stack prototypes with backend + deploy.
- v0.app and Stitch both integrate with shadcn/ui styles; pair with the
shadcn apply <style>CLI (v4) to reuse generated output.
Quick Reference
| Category | Rules | Impact | When to Use |
|---|---|---|---|
| json-render Integration | 1 | HIGH | Multi-surface output, MCP visual output, type-safe catalogs |
| Prompt Engineering | 2 | HIGH | Writing prompts for component generation |
| Quality Assurance | 2 | CRITICAL/HIGH | Reviewing and gating AI-generated code |
| Design System Integration | 2 | HIGH | Injecting tokens, refactoring for conformance |
| Tool Selection & Workflow | 2 | MEDIUM | Choosing the right AI tool, iterating prompts |
Total: 8 rules across 5 categories
Decision Table โ json-render vs v0.app vs Stitch vs Bolt Cloud vs Cursor
| Scenario | Tool | Why |
|---|---|---|
| Multi-surface / MCP visual output | json-render | Single catalog renders to any surface โ FIRST CHOICE |
| Type-safe component catalog | json-render | Schema-driven specs with per-platform registries |
| Streaming UI from AI agents | json-render | Structured JSON specs render progressively |
| New component from scratch | v0.app | Full scaffold with shadcn/ui, Tailwind, a11y. Pair with shadcn apply <style> for style consistency |
| Full-stack app with deploy | v0.app | Jan 2026 expansion โ routes, DB, auth, Vercel/Cloudflare deploy in one generation |
| Design-driven (screenshot/URL/DESIGN.md) | Google Stitch | build_site + get_screen_code / get_screen_image, up to 5 screens |
| Multi-screen flow from a visual source | Google Stitch | Strongest when grounded in an existing design |
| Full-stack prototype with persistent backend | Bolt Cloud | Cloud dev env, GitHub integration, databases |
| Incremental change in existing codebase | Cursor | Understands project context, imports, tokens |
| Refactor existing component | Cursor | Reads surrounding code, respects conventions |
| Explore visual design variations | v0.app or Stitch | v0.app for freeform, Stitch when grounded in a reference |
| Add feature to running app | Bolt Cloud | Cloud preview, full environment, persists between sessions |
| Fix bug in existing component | Cursor | Inline edits with full project awareness |
Quick Start
Structured Prompt Example
Generate a React signup form component using:
- Framework: React 19 + TypeScript
- Styling: Tailwind CSS v4 + shadcn/ui (Luma style โ rounded-4xl, shadow-md elevation)
- Style: run `npx shadcn@latest apply luma` (CLI v4, Apr 2026) after generation
- Tokens: use color.primary, color.destructive, spacing.md from our design system
- A11y: ARIA labels on all inputs, error announcements via aria-live
- States: default, loading (disabled + spinner), error (inline messages), success
- Responsive: stack on mobile (<640px), 2-col on desktopReview Example โ After AI Generation
// AI generated: hardcoded hex value
<button className="bg-[#3b82f6] text-white px-4 py-2">Submit</button>
// After human review: design token applied
<Button variant="default" size="md">Submit</Button>Rule Details
json-render Integration
json-render is the first choice for AI UI generation when output must render across multiple surfaces (web, mobile, CLI, MCP). Define a catalog of components once, generate JSON specs from AI, and render on any target surface. See ork:json-render-catalog for catalog authoring patterns.
| Rule | File | Key Pattern |
|---|---|---|
| json-render Patterns | rules/json-render-patterns.md | Catalog-first: define once, render anywhere via per-platform registries |
Prompt Engineering
Structured prompts that specify framework, tokens, a11y, and states upfront.
| Rule | File | Key Pattern |
|---|---|---|
| Prompt Patterns | rules/ai-prompt-patterns.md | Constraint-first prompts with framework, tokens, a11y |
| Iteration Patterns | rules/ai-iteration-patterns.md | Multi-pass prompts for complex interactive states |
Quality Assurance
Systematic review and CI gating for AI-generated components.
| Rule | File | Key Pattern |
|---|---|---|
| Review Checklist | rules/ai-review-checklist.md | 10-point checklist for every AI-generated component |
| CI Gate | rules/ai-ci-gate.md | Automated quality gates before merge |
Design System Integration
Ensuring AI output uses design tokens and conforms to the design system.
| Rule | File | Key Pattern |
|---|---|---|
| Token Injection | rules/ai-token-injection.md | Pass token names in prompts, reject hardcoded values |
| Refactoring Conformance | rules/ai-refactoring-conformance.md | Steps to refactor raw AI output for design system |
Tool Selection & Workflow
Choosing the right AI tool and iterating effectively.
| Rule | File | Key Pattern |
|---|---|---|
| Tool Selection | rules/ai-tool-selection.md | Match tool to use case: v0, Bolt, Cursor |
| Iteration Patterns | rules/ai-iteration-patterns.md | Iterative refinement for complex states |
Key Principles
- Own the output โ AI generates a draft; the engineer reviews, refactors, and is accountable for what ships.
- Tokens over literals โ Never accept hardcoded colors, spacing, or typography values. Always map to design tokens.
- Constraint-first prompts โ Specify framework, tokens, shadcn style (Luma/Nova/etc.), a11y, and states upfront. Vague prompts produce vague output.
- Iterative refinement โ Complex components need 2-3 prompt passes: structure first, states second, polish third.
- CI is non-negotiable โ Every AI-generated component goes through the same CI pipeline as hand-written code.
- Accessibility by default โ Include a11y requirements in every prompt; verify with automated checks post-generation.
Anti-Patterns (FORBIDDEN)
- Shipping raw AI output โ Never merge AI-generated code without human review and design system refactoring.
- Vague prompts โ "Make a nice form" produces inconsistent, non-conformant output. Always specify constraints.
- Hardcoded hex/rgb values โ AI tools default to arbitrary colors. Replace with OKLCH design tokens.
- Skipping CI for "simple" components โ AI-generated code has the same bug surface as hand-written code.
- Using v0.app for incremental changes โ v0.app generates from scratch; use Cursor for changes within an existing codebase.
- Single-pass complex components โ Multi-state components (loading, error, empty, success) need iterative prompting.
- Trusting AI a11y claims โ AI tools add ARIA attributes inconsistently. Always verify with axe-core or Storybook a11y addon.
Detailed Documentation
| Resource | Description |
|---|---|
| references/ai-ui-tool-comparison.md | json-render vs v0 vs Bolt vs Cursor vs Copilot comparison |
| references/prompt-templates-library.md | Copy-paste prompt templates for common components |
| references/ai-ui-failure-modes.md | Top 10 failure modes and fixes |
Related Skills
ork:json-render-catalogโ json-render catalog authoring, schema validation, and registry patternsork:mcp-visual-outputโ MCP visual output rendering with json-render specsork:multi-surface-renderโ Cross-platform rendering from a single component catalogork:ui-componentsโ shadcn/ui component patterns and CVA variantsork:accessibilityโ WCAG compliance, ARIA patterns, screen reader supportork:animation-motion-designโ Motion library animation patternsork:responsive-patternsโ Responsive layout and container query patternsork:design-systemโ Design token architecture and theming
Rules (8)
CI Gate for AI-Generated UI โ HIGH
CI Gate for AI-Generated UI
Every AI-generated component must pass the same CI pipeline as hand-written code. AI tools produce plausible output that passes visual inspection but fails automated checks โ especially accessibility, type safety, and bundle size.
Incorrect:
# Skipping CI because "it's just a simple component from v0"
# No lint, no a11y check, no visual regression
name: Quick Deploy
on: push
jobs:
deploy:
steps:
- uses: actions/checkout@v4
- run: npm run build
- run: npm run deploy # straight to productionCorrect:
name: UI Component CI
on: pull_request
jobs:
quality-gate:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- run: npm ci
# 1. Type check โ AI often generates implicit any
- run: npx tsc --noEmit
# 2. Lint โ catches unused imports, console.log, bad patterns
- run: npx eslint 'src/components/**/*.{ts,tsx}' --max-warnings 0
# 3. Unit tests โ component renders without errors
- run: npx vitest run --reporter=verbose
# 4. Accessibility โ axe-core catches WCAG violations
- run: npx storybook build
- run: npx concurrently -k -s last \
"npx http-server storybook-static -p 6006 -s" \
"npx wait-on http://localhost:6006 && npx test-storybook --url http://localhost:6006"
# 5. Visual regression โ catches unintended visual changes
- run: npx playwright test --project=visual
# 6. Bundle size โ AI components may import entire libraries
- run: npx size-limitRequired CI Checks
| Check | Tool | What It Catches |
|---|---|---|
| Type safety | tsc --noEmit | Implicit any, missing props, wrong event types |
| Lint | ESLint + Prettier | Unused imports, console.log, formatting |
| Unit tests | Vitest + Testing Library | Render errors, missing error boundaries |
| Accessibility | Storybook a11y addon + axe-core | Missing labels, bad ARIA, color contrast |
| Visual regression | Playwright screenshots | Unintended layout shifts, styling bugs |
| Bundle size | size-limit | Bloated imports (import * from "lucide-react") |
Storybook A11y Test Setup
// .storybook/test-runner.ts
import { checkA11y } from "@storybook/test-runner";
import { configureAxe } from "axe-playwright";
export default {
async postVisit(page) {
await configureAxe(page, {
rules: [
{ id: "color-contrast", enabled: true },
{ id: "label", enabled: true },
{ id: "button-name", enabled: true },
],
});
await checkA11y(page);
},
};Key rules:
- AI-generated components go through the exact same CI as hand-written code โ no fast lanes
- Run
tsc --noEmitbefore anything else โ type errors indicate fundamental issues - Use
--max-warnings 0for ESLint โ AI-generated code often has warnings that hide bugs - Test bundle size โ AI tools import entire icon libraries instead of individual icons
- Add Storybook stories for every AI-generated component โ they serve as both docs and test targets
Reference: https://storybook.js.org/docs/writing-tests/accessibility-testing
Iterative Prompt Patterns for Complex UI States โ MEDIUM
Iterative Prompt Patterns for Complex UI States
Complex interactive components require 2-3 prompt passes. A single prompt cannot reliably produce all states (default, loading, error, empty, success, disabled) with correct transitions between them.
Incorrect:
# Single prompt for everything โ AI drops states, mixes concerns
"Generate a data table with sorting, filtering, pagination,
loading states, error handling, empty states, bulk selection,
row actions, column resizing, and keyboard navigation"Result: AI generates the happy path (data visible, sorted) but produces broken loading spinners, missing error boundaries, and no empty state.
Correct โ 3-Pass Approach:
Pass 1: Structure and Happy Path
Generate a DataTable component:
- Framework: React 19 + TypeScript
- Library: @tanstack/react-table v8
- Features: sorting (multi-column), filtering (column + global), pagination
- Styling: Tailwind + shadcn/ui Table primitives
- Props: data: T[], columns: ColumnDef<T>[]
- DO NOT handle loading/error yet โ happy path onlyPass 2: Interactive States
Extend the DataTable from Pass 1. Add these states:
- Loading: skeleton rows (5 rows), disabled sort/filter controls
- Error: error banner with retry button, table hidden
- Empty: illustration + "No results" message + clear filters CTA
- Partial loading: pagination shows spinner, existing data stays visible
Keep the happy path code unchanged.Pass 3: Advanced Interactions
Add to the DataTable:
- Bulk selection: checkbox column, "Select all" header, selected count banner
- Row actions: dropdown menu (Edit, Delete, Duplicate) per row
- Keyboard: Arrow keys between rows, Enter to expand, Escape to deselect
- Focus management: focus returns to trigger after action menu closesState Transition Map
Define state transitions before prompting to ensure completeness:
idle โ loading โ success (show data)
โ error (show error + retry)
โ empty (show empty state)
success โ loading (pagination/sort change) โ success | error
error โ loading (retry clicked) โ success | errorWhen to Use Multi-Pass
| Component Complexity | Passes | Example |
|---|---|---|
| Static display | 1 | Card, badge, avatar |
| Single interaction | 1-2 | Button with loading, toggle |
| Form with validation | 2 | Signup form, settings panel |
| Data-driven with states | 3 | Data table, dashboard, kanban |
| Full page with routing | 3+ | Dashboard page, wizard flow |
Key rules:
- Use single-pass only for static or single-interaction components
- Always separate structure (Pass 1) from states (Pass 2) from advanced interactions (Pass 3)
- Define the state transition map before writing any prompt
- Tell the AI to "keep existing code unchanged" in follow-up passes โ prevents regression
- Review each pass output before proceeding to the next โ errors compound across passes
Reference: https://tanstack.com/table/latest
AI Prompt Patterns for UI Generation โ HIGH
AI Prompt Patterns for UI Generation
Structure every AI UI prompt with explicit constraints: framework, design tokens, accessibility requirements, and expected states. Constraint-first prompts reduce rework by 60-80% compared to freeform requests.
Incorrect:
Make me a nice signup form with email and password fields.This produces:
- Arbitrary colors and spacing (not from your design system)
- Missing ARIA labels and error announcements
- No loading, error, or success states
- Inconsistent with existing codebase patterns
Correct:
Generate a signup form component:
Framework: React 19 + TypeScript strict mode
Styling: Tailwind CSS v4 + shadcn/ui primitives (Button, Input, Label, Card)
shadcn style: Luma (rounded-4xl buttons/cards, shadow-md elevation, gap-6 spacing)
โ or read from components.json โ "style" field for project-specific style
Design tokens:
- Colors: use oklch(var(--color-primary)), oklch(var(--color-destructive))
- Spacing: gap-4 for form fields, p-6 for card padding
- Typography: text-sm for labels, text-base for inputs
Accessibility:
- <label> elements linked to inputs via htmlFor
- aria-describedby on inputs pointing to error messages
- aria-live="polite" region for form-level errors
- Focus visible ring on all interactive elements
States: default, loading (submit disabled + Loader2 spinner),
field-error (inline per-field), form-error (top banner), success
Validation: zod schema, react-hook-form integration
Responsive: single column always, max-w-md centeredPrompt Structure Template
Generate a [component type] component:
Framework: [React/Next.js version] + TypeScript
Styling: [Tailwind version] + [UI library] + [shadcn style: Luma/Vega/Nova/etc.]
Design tokens: [list token names and where to use them]
Accessibility: [specific ARIA patterns needed]
States: [enumerate all states]
Responsive: [breakpoint behavior]
Integration: [form library, state management, API calls]Key rules:
- Always specify the UI library AND shadcn style (e.g., "shadcn/ui Luma style") โ AI tools default to raw HTML and generic classes otherwise
- List design token variable names explicitly โ AI cannot infer your token system
- Enumerate every state the component must handle โ AI skips states you do not mention
- Include responsive breakpoints โ AI defaults to desktop-only layouts
- Specify TypeScript strictness โ AI generates
anytypes without explicit instruction
Reference: https://v0.dev/docs
Refactoring AI Output for Design System Conformance โ HIGH
Refactoring AI Output for Design System Conformance
Raw AI-generated components must be refactored through a 5-step process before merging: extract tokens, apply CVA variants, add TypeScript props, wire to design system, and verify theme compatibility.
Incorrect:
// Raw v0 output โ shipped as-is
export function StatusBadge({ status }: { status: string }) {
return (
<span
className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium
${status === "active" ? "bg-green-100 text-green-800" : ""}
${status === "inactive" ? "bg-gray-100 text-gray-800" : ""}
${status === "error" ? "bg-red-100 text-red-800" : ""}`}
>
{status}
</span>
)
}Correct:
// After 5-step refactoring โ design system conformant
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",
{
variants: {
variant: {
active: "bg-emerald-500/15 text-emerald-700 dark:text-emerald-400",
inactive: "bg-muted text-muted-foreground",
error: "bg-destructive/15 text-destructive",
},
},
defaultVariants: { variant: "inactive" },
}
)
interface StatusBadgeProps
extends React.HTMLAttributes<HTMLSpanElement>,
VariantProps<typeof badgeVariants> {
status: "active" | "inactive" | "error"
}
export function StatusBadge({
status,
className,
...props
}: StatusBadgeProps) {
return (
<span className={cn(badgeVariants({ variant: status }), className)} {...props}>
{status}
</span>
)
}The 5-Step Refactoring Process
- Extract tokens โ Replace all hardcoded colors (
green-100,#3b82f6) with semantic tokens (bg-primary,text-muted-foreground) - Apply CVA variants โ Convert conditional className strings to
cva()variant definitions withdefaultVariants - Add TypeScript props โ Create explicit interface extending HTML element props +
VariantProps<typeof variants> - Wire to design system โ Import
cn()utility, acceptclassNameprop for composition, useforwardRefif needed - Verify theme โ Test light mode, dark mode, and high contrast โ tokens must resolve correctly in all themes
Refactoring Checklist
| Step | Before (AI output) | After (conformant) |
|---|---|---|
| Colors | bg-blue-500, text-gray-600 | bg-primary, text-muted-foreground |
| Variants | Ternary chains in className | cva() with named variants |
| Props | \{ status: string \} | StatusBadgeProps with union types |
| Composition | No className prop | cn(variants(), className) |
| Theme | Light mode only | Verified in light, dark, high contrast |
Key rules:
- Never ship raw AI output โ always run the 5-step process
- Use CVA for any component with 2+ visual variants โ AI outputs ternary chains instead
- Union types over
stringfor variant props โ"active" | "inactive"notstring - Always accept
classNameand spread...propsfor composition - Test dark mode โ AI tools generate with light backgrounds, tokens may not resolve in dark
Reference: https://cva.style/docs
AI-Generated UI Review Checklist โ HIGH
AI-Generated UI Review Checklist
Every AI-generated component must pass this 10-point checklist before merging. AI tools produce plausible but subtly incorrect code โ systematic review catches issues that look correct at a glance.
Incorrect:
// Accepting v0 output as-is โ multiple hidden issues
export function UserCard({ user }) { // no TypeScript props
return (
<div className="bg-[#f8fafc] p-4 rounded-lg shadow-md" // hardcoded color
onClick={() => navigate(`/users/${user.id}`)}> // div with onClick, no keyboard
<img src={user.avatar} className="w-12 h-12 rounded-full" /> // no alt
<h3 className="text-[18px] font-semibold">{user.name}</h3> // hardcoded size
<p className="text-[#64748b]">{user.role}</p> // hardcoded color
</div>
)
}Correct:
// After systematic review โ all 10 points addressed
interface UserCardProps {
user: User
onSelect?: (userId: string) => void
}
export function UserCard({ user, onSelect }: UserCardProps) {
return (
<button
type="button"
className="bg-muted p-4 rounded-lg shadow-md text-left w-full
focus-visible:ring-2 focus-visible:ring-ring"
onClick={() => onSelect?.(user.id)}
>
<img
src={user.avatar}
alt={`${user.name} avatar`}
className="size-12 rounded-full"
/>
<h3 className="text-lg font-semibold">{user.name}</h3>
<p className="text-muted-foreground">{user.role}</p>
</button>
)
}The 10-Point Checklist
| # | Check | What to Look For |
|---|---|---|
| 1 | Semantic HTML | <button> not <div onClick>, <nav>, <main>, <article> |
| 2 | ARIA roles | Interactive elements have labels, live regions for dynamic content |
| 3 | Design tokens | No hardcoded hex/rgb/hsl โ use Tailwind semantic classes (bg-primary) |
| 4 | TypeScript props | Explicit interface, no any, proper event handler types |
| 5 | Responsive | Works at 320px, 768px, 1024px+ โ no horizontal overflow |
| 6 | Keyboard navigation | Tab order, Enter/Space activation, Escape to close |
| 7 | Focus indicators | focus-visible:ring-2 on all interactive elements |
| 8 | Image alt text | Meaningful alt on images, alt="" for decorative |
| 9 | Error states | Loading, error, empty states handled โ not just happy path |
| 10 | No console/debug | Remove console.log, TODO comments, placeholder data |
Key rules:
- Run through all 10 points for every AI-generated component โ no exceptions
- Flag any hardcoded color, spacing, or typography value as a blocking issue
- Interactive
<div>or<span>elements must be converted to<button>or<a> - Missing TypeScript props interface is a blocking issue โ AI often uses implicit
any
Reference: https://www.w3.org/WAI/ARIA/apg/patterns/
Design Token Injection in AI Prompts โ HIGH
Design Token Injection in AI Prompts
Always pass design token variable names in AI prompts. AI tools cannot infer your token system โ they default to hardcoded values that break dark mode, theme switching, and design system consistency.
Incorrect:
# Vague color instruction
"Make a blue primary button with a red error state"AI output:
// Hardcoded values โ breaks dark mode, ignores design system
<button className="bg-[#3b82f6] hover:bg-[#2563eb] text-white">
Submit
</button>
<p className="text-[#ef4444]">Error message</p>Correct:
# Explicit token names in prompt
"Use these design tokens:
- Primary: bg-primary, text-primary-foreground, hover:bg-primary/90
- Destructive: text-destructive
- Muted: bg-muted, text-muted-foreground
- Border: border-border
- Ring: ring-ring for focus states
All colors use OKLCH via CSS custom properties."AI output:
// Token-based โ works with dark mode, respects design system
<Button variant="default">Submit</Button>
<p className="text-destructive">Error message</p>Token Injection Template
Include this block in every AI UI prompt:
Design tokens (use these exact class names):
Colors:
- bg-primary / text-primary-foreground โ main actions
- bg-secondary / text-secondary-foreground โ secondary actions
- bg-destructive / text-destructive-foreground โ errors, delete
- bg-muted / text-muted-foreground โ disabled, hints
- border-border โ all borders
- ring-ring โ focus rings
Spacing: p-4 (card), p-6 (section), gap-4 (form fields), gap-2 (inline)
Radius: rounded-md (buttons), rounded-lg (cards), rounded-full (avatars)
Typography: text-sm (labels), text-base (body), text-lg (headings)
DO NOT use hardcoded hex, rgb, or hsl values.
DO NOT use arbitrary Tailwind values like bg-[#3b82f6].OKLCH Token Architecture
/* Modern OKLCH tokens โ wider gamut, perceptually uniform */
:root {
--color-primary: oklch(0.55 0.2 250);
--color-primary-foreground: oklch(0.98 0.005 250);
--color-destructive: oklch(0.55 0.2 25);
--color-muted: oklch(0.95 0.01 250);
--color-muted-foreground: oklch(0.55 0.01 250);
}
.dark {
--color-primary: oklch(0.7 0.18 250);
--color-destructive: oklch(0.65 0.2 25);
--color-muted: oklch(0.2 0.01 250);
--color-muted-foreground: oklch(0.65 0.01 250);
}Key rules:
- Include the full token injection block in every AI prompt โ AI tools cannot read your CSS variables
- Flag any
bg-[#...],text-[#...], or inlinestyle=\{\{ color: "..." \}\}as a blocking review issue - After generation, search-and-replace any remaining hardcoded values with token classes
- Verify dark mode works โ hardcoded values are invisible against dark backgrounds
- Use OKLCH for new token definitions โ wider gamut and perceptually uniform lightness
Reference: https://ui.shadcn.com/docs/theming
AI Tool Selection for UI Generation โ MEDIUM
AI Tool Selection for UI Generation
Match the AI tool to the task type. json-render is the first choice for multi-surface, MCP output, and type-safe catalog workflows. Each tool has a sweet spot โ using it outside that range produces poor results or unnecessary rework.
Incorrect:
# Using v0 to fix a bug in an existing component
# v0 generates from scratch โ it cannot read your codebase
# Result: a new component that ignores your existing imports, tokens, and patterns
Prompt to v0: "Fix the pagination bug in our DataTable component"
# v0 output: a completely new DataTable with different props, different stylingCorrect:
# Use Cursor for incremental changes โ it reads your project context
# Cursor understands your imports, tokens, component library, and patterns
# In Cursor, with your DataTable.tsx open:
"Fix the pagination: currentPage should reset to 1 when filters change.
Use the existing useDataTable hook and keep the PageInfo type."Selection Matrix
| Task | Best Tool | Why | Avoid |
|---|---|---|---|
| Multi-surface / MCP output | json-render | Single catalog, renders anywhere โ FIRST CHOICE | v0 (single-surface only) |
| Type-safe component catalog | json-render | Schema-driven specs with per-platform registries | Bolt (no catalog abstraction) |
| Streaming UI from AI agents | json-render | Structured JSON specs render progressively | Cursor (no streaming output) |
| New component from scratch | v0 | Best scaffold quality, shadcn/ui native | Cursor (no visual preview) |
| Full-stack prototype | Bolt | Backend + frontend + deployment in one | v0 (frontend only) |
| Bug fix in existing code | Cursor | Reads project context, inline edits | v0 (generates from scratch) |
| Refactor existing component | Cursor | Understands imports and dependencies | Bolt (overkill) |
| Explore design variations | v0 | Fast visual iteration, multiple options | Cursor (no visual preview) |
| Add API route + UI | Bolt | Full-stack awareness, hot reload | v0 (no backend) |
| Component library page | v0 | Generates multiple variants at once | Cursor (one-at-a-time) |
| Complex form with validation | v0 then Cursor | v0 for scaffold, Cursor for integration | Bolt (form-only is overkill) |
Hybrid Workflow
For maximum efficiency, combine tools:
- v0 โ Generate initial component scaffold with visual preview
- Copy โ Paste output into your project
- Cursor โ Refactor to match your design system, add project-specific logic
- CI โ Run lint, a11y, visual regression checks
Key rules:
- Use json-render when output must render on multiple surfaces, stream via MCP, or enforce a type-safe catalog โ it is the first choice
- Use v0 for net-new components where visual preview accelerates design decisions
- Use Cursor for any change that touches existing code โ it reads project context
- Use Bolt only when you need backend + frontend together in a prototype
- Never use v0 for bug fixes or refactoring โ it generates from scratch and ignores your codebase
- Combine tools: json-render for catalog definition, v0 for scaffold, Cursor for integration and refinement
Reference: https://v0.dev, https://bolt.new, https://cursor.com
json-render Integration Patterns โ HIGH
json-render Integration Patterns
json-render is the first choice when AI-generated UI must render across multiple surfaces, stream through MCP, or enforce type-safe component catalogs. Use v0/Bolt/Cursor when you need quick prototyping (v0), full-stack scaffolding (Bolt), or incremental edits in an existing codebase (Cursor).
When to Use json-render (FIRST CHOICE)
- Multi-surface output โ one catalog renders to web, mobile, CLI, or any custom surface
- MCP visual output โ structured JSON specs travel over MCP and render on the host surface
- Type-safe catalogs โ schema-driven component definitions with compile-time validation
- Streaming UI โ AI agents emit JSON specs progressively; renderers display as specs arrive
When to Use v0 / Bolt / Cursor Instead
- Quick visual prototyping โ v0 gives instant visual preview with shadcn/ui
- Full-stack prototype โ Bolt scaffolds backend + frontend + deployment together
- Incremental changes โ Cursor reads your codebase context for inline edits and refactors
Integration Pattern
- Define catalog โ declare component schemas in a json-render catalog (see
ork:json-render-catalog) - AI generates spec โ the AI produces a JSON spec conforming to the catalog schema
- Render on target surface โ per-platform registries map specs to native components
Incorrect:
// Building separate component trees per platform โ duplicated logic, drift risk
const WebCard = ({ title, body }) => <div className="card">...</div>;
const MobileCard = ({ title, body }) => <View style={styles.card}>...</View>;
const CLICard = ({ title, body }) => chalk.bold(title) + '\n' + body;Correct:
// Single json-render catalog with per-platform registries
// 1. Define once
const catalog = defineCatalog({
Card: { props: { title: 'string', body: 'string' } },
});
// 2. AI generates a spec
const spec = { type: 'Card', props: { title: 'Hello', body: 'World' } };
// 3. Each platform registers its own renderer
webRegistry.register('Card', ({ title, body }) => <div>...</div>);
mobileRegistry.register('Card', ({ title, body }) => <View>...</View>);
// 4. Render on any surface from the same spec
render(spec, webRegistry); // React DOM
render(spec, mobileRegistry); // React NativeReferences (3)
AI UI Generation Failure Modes
AI UI Generation Failure Modes
Top 10 failure modes of AI-generated UI components, ordered by frequency. Each includes detection method and fix.
1. Hardcoded Color Values
Frequency: Very common (80%+ of AI output)
Problem: AI generates bg-[#3b82f6], text-[#64748b], or inline style=\{\{ color: "#..." \}\} instead of design tokens.
Detection: grep -rn 'bg-\[#\|text-\[#\|border-\[#\|style=\{\{' src/components/
Fix: Replace with semantic token classes: bg-primary, text-muted-foreground, border-border.
2. Non-Semantic HTML
Frequency: Very common
Problem: AI uses <div onClick> instead of <button>, <div> instead of <nav>, <span> for headings.
Detection: ESLint jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events.
Fix: Replace with semantic elements: <button>, <nav>, <main>, <article>, <section>.
3. Missing Loading/Error States
Frequency: Common (60%+)
Problem: AI generates the happy path only. No loading skeleton, no error boundary, no empty state.
Detection: Search for state handling: grep -rn 'isLoading\|isError\|isEmpty' component.tsx. If absent, states are missing.
Fix: Use iterative prompting (Pass 2) to add states. See rules/ai-iteration-patterns.md.
4. Implicit any TypeScript
Frequency: Common
Problem: AI generates function Card(\{ data \}) without TypeScript interface, creating implicit any.
Detection: tsc --noEmit with strict: true in tsconfig.
Fix: Add explicit props interface with union types for variants.
5. Bloated Imports
Frequency: Common
Problem: AI imports entire icon libraries (import * from "lucide-react") or unused dependencies.
Detection: size-limit CI check, ESLint no-unused-imports rule.
Fix: Import individual icons: import \{ Search, ChevronDown \} from "lucide-react".
6. Missing Focus Management
Frequency: Common
Problem: No focus-visible:ring on interactive elements, no focus trap in modals, no focus return after close.
Detection: Tab through the component โ if focus is invisible or gets lost, it fails.
Fix: Add focus-visible:ring-2 focus-visible:ring-ring to all interactive elements. Use Radix Dialog for focus trapping.
7. Incorrect ARIA Usage
Frequency: Moderate (40%+)
Problem: AI adds ARIA attributes incorrectly โ aria-label on non-interactive elements, redundant roles, conflicting attributes.
Detection: axe-core or Storybook a11y addon catches most ARIA errors.
Fix: Follow WAI-ARIA Authoring Practices. Remove ARIA when semantic HTML conveys the same meaning.
8. Desktop-Only Layout
Frequency: Moderate
Problem: AI generates layouts that overflow on mobile. Fixed widths, no responsive breakpoints, horizontal scroll.
Detection: Chrome DevTools responsive mode at 320px width.
Fix: Use Tailwind responsive prefixes (sm:, md:, lg:). Test at 320px, 768px, 1024px.
9. String Concatenation for Classes
Frequency: Moderate
Problem: AI generates className=\{"base " + (active ? "bg-blue-500" : "bg-gray-200")\} instead of CVA or cn().
Detection: Grep for template literals or string concatenation in className.
Fix: Use cn() from @/lib/utils or CVA for variant-based styling. See rules/ai-refactoring-conformance.md.
10. Stale or Deprecated APIs
Frequency: Occasional
Problem: AI generates code using deprecated APIs โ framer-motion (now motion/react), React class components, old Next.js pages router patterns.
Detection: Code review, comparing against current documentation.
Fix: Specify exact library versions and import paths in prompts. See rules/ai-prompt-patterns.md.
Quick Detection Script
Run this after receiving AI-generated components:
# Check for common failure modes in AI-generated components
echo "=== Hardcoded colors ==="
grep -rn 'bg-\[#\|text-\[#\|border-\[#' "$1"
echo "=== Non-semantic interactive elements ==="
grep -rn '<div.*onClick\|<span.*onClick' "$1"
echo "=== Missing TypeScript props ==="
grep -rn 'function.*{.*})\s*{' "$1" | grep -v 'Props\|interface\|type '
echo "=== Bloated imports ==="
grep -rn 'import \*' "$1"
echo "=== String class concatenation ==="
grep -rn "className={['\"]" "$1"AI UI Tool Comparison โ json-render vs v0 vs Bolt vs Cursor vs Copilot
AI UI Tool Comparison
Detailed comparison of AI UI generation tools as of 2026. Each tool excels in a specific workflow โ none is universally best.
Feature Comparison
| Feature | json-render | v0 (Vercel) | Bolt (StackBlitz) | Cursor | GitHub Copilot |
|---|---|---|---|---|---|
| Primary use | Multi-surface catalog rendering | Component scaffolding | Full-stack prototyping | In-editor coding | Inline autocomplete |
| Output | JSON spec + per-platform renderers | React + shadcn/ui + Tailwind | Full app (FE + BE + DB) | Inline edits / files | Line/block completions |
| Visual preview | Via target surface renderer | Yes (live) | Yes (full app) | No | No |
| Project context | Catalog-scoped | None (standalone) | Partial (within session) | Full (reads project) | File-level |
| Framework | Any (React, RN, CLI, MCP) | React/Next.js | React, Vue, Svelte | Any | Any |
| Design system aware | Schema-enforced catalogs | shadcn/ui built-in | Configurable | Reads your codebase | File-level patterns |
| Backend support | N/A (render layer) | No | Yes (Node, Python, etc.) | Yes (via project) | Yes (via file) |
| Deployment | Embeds in any host | Vercel one-click | StackBlitz preview | N/A (local) | N/A (local) |
| Collaboration | Catalog as code (Git) | Share via URL | Share via URL | Git-based | Git-based |
Strengths and Weaknesses
json-render (FIRST CHOICE)
Strengths:
- Single catalog renders to any surface โ web, mobile, CLI, MCP
- Type-safe component specs with schema validation at build time
- AI agents generate structured JSON specs that render progressively (streaming UI)
- Platform-agnostic โ no framework lock-in, per-platform registries map to native components
- Ideal for MCP visual output where structured data must travel across tool boundaries
Weaknesses:
- Not a visual prototyping tool โ no instant preview like v0
- Requires upfront catalog definition before rendering
- No backend scaffolding โ focused on the render layer only
- Learning curve for catalog schema authoring
When to use: Multi-surface output, MCP visual rendering, type-safe component catalogs, streaming AI UI. This is the first choice for any workflow where output must render on more than one surface.
v0 (Vercel)
Strengths:
- Best-in-class component scaffolding quality
- Native shadcn/ui and Tailwind integration
- Visual preview with instant iteration
- Generates accessible components by default
- Multiple design variations per prompt
Weaknesses:
- No project context โ cannot read your codebase
- React/Next.js only โ no Vue, Svelte, Angular
- Frontend only โ no backend or API routes
- Output requires refactoring for design system conformance
- Cannot modify existing components
Bolt (StackBlitz)
Strengths:
- Full-stack generation (frontend + backend + database)
- Live preview with hot reload in browser
- Supports multiple frameworks (React, Vue, Svelte)
- Can scaffold entire applications from a description
- Built-in deployment previews
Weaknesses:
- Lower component quality than v0 for individual components
- Generated backend code needs significant security review
- Large output surface area โ more to review
- Token/session limits for complex applications
Cursor
Strengths:
- Full project context โ reads imports, types, tokens
- Inline edits within existing files
- Multi-file refactoring with dependency awareness
- Works with any framework or language
- Understands your design system from codebase
Weaknesses:
- No visual preview โ must run the app to see results
- Slower for greenfield components (no scaffold templates)
- Quality depends on existing code quality (garbage in, garbage out)
- Composer mode can make unintended changes across files
GitHub Copilot
Strengths:
- Always available in VS Code / JetBrains
- Good at completing patterns from surrounding code
- Low friction โ inline suggestions as you type
- Workspace-level context with
@workspace
Weaknesses:
- Autocomplete granularity โ not full component generation
- Limited multi-file awareness compared to Cursor
- Cannot generate visual designs or previews
- Suggestions vary in quality without explicit prompting
Pricing (2026)
| Tool | Free Tier | Pro Tier | Team Tier |
|---|---|---|---|
| v0 | 10 generations/day | $20/mo (unlimited) | $30/user/mo |
| Bolt | Limited usage | $20/mo | Custom |
| Cursor | 50 completions/day | $20/mo | $40/user/mo |
| Copilot | Free for OSS | $10/mo | $19/user/mo |
Pricing subject to change. Check official sites for current rates.
Recommendation Matrix
| You Need | Use | Why |
|---|---|---|
| Multi-surface / MCP visual output | json-render | Single catalog renders anywhere โ FIRST CHOICE |
| Type-safe component catalog | json-render | Schema-driven specs with compile-time validation |
| Streaming UI from AI agents | json-render | Structured JSON specs render progressively |
| A new shadcn/ui component | v0 | Best scaffold quality, visual iteration |
| A full prototype to demo | Bolt | End-to-end app in minutes |
| To add a feature to your app | Cursor | Reads your codebase, respects patterns |
| Quick inline completions | Copilot | Low friction, always available |
| A component + its API route | Bolt or v0 + Cursor | Combine tools for best results |
AI UI Prompt Templates Library
AI UI Prompt Templates Library
Copy-paste prompt templates for common component types. Each template includes framework, tokens, a11y, and state requirements. Customize the token names and specific requirements for your project.
1. Form Component
Generate a [form purpose] form component:
Framework: React 19 + TypeScript strict mode
Styling: Tailwind CSS v4 + shadcn/ui (Form, Input, Label, Button, Select)
Validation: zod schema + react-hook-form v7
Design tokens:
- bg-card for form container, border-border for field borders
- text-destructive for error messages, text-muted-foreground for hints
- ring-ring for focus states
Accessibility:
- <Label> linked to each input via htmlFor
- aria-describedby pointing to error/hint text
- aria-invalid="true" on fields with errors
- aria-live="polite" region for form-level success/error
States: default, field-error (inline), form-error (banner), loading (disabled + spinner), success (toast)
Responsive: single column, max-w-lg centered
Submit: async handler returning { success: boolean; error?: string }2. Data Table
Generate a data table component:
Framework: React 19 + TypeScript
Library: @tanstack/react-table v8
Styling: Tailwind CSS v4 + shadcn/ui (Table, Button, Input, DropdownMenu)
Features: sorting (multi-column), column filtering, global search, pagination (10/25/50 per page)
Design tokens:
- bg-card for table container, border-border for cell borders
- bg-muted/50 for header row, hover:bg-muted for row hover
- text-muted-foreground for empty state text
Accessibility:
- role="grid" with proper aria-sort on sortable columns
- aria-label on action buttons, sr-only text for icon-only controls
- Keyboard: arrow keys for cell navigation, Enter for sort
States: loading (skeleton rows), empty (illustration + message), error (retry banner)
Props: data: T[], columns: ColumnDef<T>[], onRowClick?: (row: T) => void3. Dashboard Card
Generate a dashboard metric card component:
Framework: React 19 + TypeScript
Styling: Tailwind CSS v4 + shadcn/ui (Card, CardHeader, CardContent)
Design tokens:
- bg-card, border-border for card container
- text-muted-foreground for label, text-foreground for value
- text-emerald-600 dark:text-emerald-400 for positive trend
- text-destructive for negative trend
Content: icon (Lucide), label, value (formatted number), trend (% with arrow)
Accessibility: aria-label describing the full metric context
Animation: value count-up on mount using Motion
States: loading (skeleton), error (dash value), stale (muted opacity + "Updated 5m ago")
Responsive: full width on mobile, fixed 280px on desktop grid4. Navigation Component
Generate a responsive navigation component:
Framework: React 19 + TypeScript + Next.js App Router
Styling: Tailwind CSS v4 + shadcn/ui (Sheet, Button, NavigationMenu)
Design tokens:
- bg-background/95 backdrop-blur for sticky header
- border-border for bottom border
- text-foreground for links, text-primary for active link
Accessibility:
- <nav aria-label="Main navigation">
- aria-current="page" on active link
- Mobile: Sheet with focus trap, Escape to close
- Skip-to-content link as first focusable element
Responsive:
- Desktop (>=1024px): horizontal nav with dropdown menus
- Mobile (<1024px): hamburger icon โ Sheet slide-in panel
States: default, mobile-open, dropdown-open
Links: [{label, href, children?: [{label, href}]}]5. Modal / Dialog
Generate a confirmation dialog component:
Framework: React 19 + TypeScript
Styling: Tailwind CSS v4 + shadcn/ui (Dialog, Button)
Design tokens:
- bg-background for dialog surface
- bg-background/80 for overlay backdrop
- text-destructive for destructive action variant
Accessibility:
- Focus trap within dialog (shadcn/ui Dialog handles this)
- aria-labelledby pointing to title, aria-describedby pointing to description
- Escape key closes, click outside closes (configurable)
- Return focus to trigger element on close
Props: open, onOpenChange, title, description, confirmLabel, onConfirm, variant: "default" | "destructive"
States: default, loading (confirm button disabled + spinner), success (auto-close)
Animation: Motion scale + opacity entrance/exit6. Empty State
Generate an empty state component:
Framework: React 19 + TypeScript
Styling: Tailwind CSS v4 + shadcn/ui (Button)
Design tokens:
- text-muted-foreground for description
- bg-muted for illustration container circle
Content: icon (Lucide, 48px), title, description, primary CTA button, optional secondary link
Accessibility: role="status" with aria-label summarizing the empty state
Props: icon: LucideIcon, title: string, description: string,
action?: { label: string; onClick: () => void },
secondaryAction?: { label: string; href: string }
Responsive: centered, max-w-md, 64px vertical paddingUsage Notes
- Replace token names with your project's actual tokens
- Add project-specific imports (your
cn()utility path, component library path) - After generation, run through the review checklist (
rules/ai-review-checklist.md) - Refactor for design system conformance (
rules/ai-refactoring-conformance.md)
Agent Orchestration
Agent orchestration patterns for agentic loops, multi-agent coordination, alternative frameworks, and multi-scenario workflows. Use when building autonomous agent loops, coordinating multiple agents, evaluating CrewAI/AutoGen/Swarm, or orchestrating complex multi-step scenarios.
Analytics
Queries local analytics across OrchestKit projects for agent usage, skill frequency, hook timing, team activity, session replay, cost estimation, and model delegation trends. Privacy-safe with hashed project IDs. Supports time-range filtering and comparative analysis. Use when reviewing performance, estimating costs, or understanding usage patterns.
Last updated on