Rapid UI/UX Prototyping with Storybook and Claude Code
How I use Storybook's component isolation to rapidly prototype UI variations with Claude Code, comparing multiple approaches side-by-side before committing to a design.
I run five Storybook environments across different projects, and for a long time they were only useful for UI inspection. The pattern changed when I started treating Storybook as the primary prototyping surface for AI-assisted development.
The shift is simple: instead of asking an assistant for one implementation and iterating by hand, I ask for multiple complete approaches up front. The trade-off is a little more prompt effort, and a lot more decision confidence.
Why component isolation matters with AI
Storybook gives immediate, deterministic feedback without coupling every experiment to full application state. That matters because AI-generated UI code often looks fine in context yet fails for the exact variation I need next.
In this environment I can compare multiple variants quickly. Each variant stays runnable, inspectable, and testable in isolation. It is effectively a decision matrix for interfaces.
The loop is now: generate variants, compare in tabs, keep the winner, discard the rest.
How I structure a prompt for useful output
The most important rule is to constrain the ask with testable outcomes: variants, states, constraints, and accepted stack choices. A typical request looks like this.
I need a Button component with:
variants: primary, secondary, ghost, danger, link, success.
sizes: sm, md, lg, icon.
states: loading, disabled.
full width option.
Use TypeScript and Tailwind. Generate Storybook stories for each variant.
Then I follow with a follow-up prompt requesting multiple approaches:
Give me three approaches.
Approach 1: solid fills with subtle shadows.
Approach 2: outlined style with hover fills.
Approach 3: minimal flat style.
Generate each as a separate Storybook story so I can compare.
This is where I get leverage. One request produces a design space, not one fragile baseline.
Why this works better than app-first iteration
When I prototype directly in app code, comparison is expensive. I can only keep one implementation active, then mentally reconstruct previous attempts. With Storybook, comparison is visual, fast, and structured.
I can keep variants in separate tabs and answer: which shape, spacing, interaction state, and accessibility behavior feels strongest. That is a design decision I can make with evidence, not hope.
A real pattern for reusable variation coverage
For production components, I now prefer an AllVariants story. It gives one file-level view that proves behavior across permutations.
export const AllVariants: Story = {
render: () => (
<div className="grid grid-cols-3 gap-4">
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="danger">Danger</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
<Button variant="success">Success</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button loading>Loading</Button>
<Button disabled>Disabled</Button>
</div>
),
};
Seeing this in one page makes gaps obvious. If loading state does not communicate disabled intent, I know it immediately and ask Claude to revise only that dimension instead of regenerating the component from scratch.
Case studies from real work
On VibeCoord, this workflow turned component iteration from serial to parallel. I now ask for multiple thinking-state and deployment-widget variations and choose the best implementation from direct comparison, not from long back-and-forth prose.
On mc-print, component behavior at print dimensions is hard to reason about. Storybook’s predictable canvas with fixed paper dimensions made it possible to catch alignment and spacing defects before spending time in build pipelines.
The pattern is the same across projects: faster iteration means better decisions, not faster guessing.
function A4Sheet({ children }: { children: React.ReactNode }) {
return (
<PrintPage
paperSize="A4"
orientation="portrait"
marginMm={12}
background="white"
showGuides={false}
content={<Stack direction="column" gapMm={4} align="stretch" content={<>{children}</>} />}
/>
);
}
I use this for both UI-heavy components and print-heavy layouts. It gives me one artifact that is both visual and testable.
The pattern that keeps working
Storybook is my control surface. Claude is my variant generator. The combination is effective when I ask for options up front and compare them immediately.
The process has become: define requirement and constraints, ask for a structured variation set, compare all variants in Storybook, then promote the winning pattern into the app/library.
I still review and pick, but the loop gets shorter and the decision quality is consistently higher.
Implementation commands
# mc-ui (form-focused components)
cd /path/to/MacquarieCollege && pnpm storybook --filter=mc-ui
# mc-print (print layouts)
cd /path/to/MacquarieCollege && pnpm storybook --filter=mc-print
# ui-portfolio (portfolio components)
cd /path/to/portfolio-monorepo && pnpm --filter=@portfolio-monorepo/ui-portfolio storybook
The practical outcome is less time debating a single design and more time selecting the version that best balances accessibility, clarity, and implementation confidence.
Short notes on building AI agents in production.
One email when something worth sharing ships. No fluff, no daily cadence, no recycled growth-thread noise.
Primary use: consulting updates, governed AI workflow lessons, and major project writeups.