Prompting Vercel v0 is not like prompting a full-stack generator or an in-IDE coding agent. v0 is focused on a narrower job: generating UI — components, pages, layouts — built on React, shadcn/ui, and Tailwind by default. Prompts that describe behavior and visual intent beat prompts that describe a feature label. The loop is visual: generate, see, refine.
What v0 Is
v0 is Vercel's UI-focused AI generator. You describe a component or a page; v0 produces React code you can preview in place and copy or export into a project. The defaults are opinionated: React, Tailwind, and shadcn/ui. That is the point. The stack is what lets the output look coherent the first time rather than random.
Because v0 lives inside that opinionated surface, prompts that fight it produce worse results than prompts that lean into it. "A button that looks like a 2004 Windows XP button" is a harder ask than "a primary button with a subtle shadow and a pressed state." The second uses the defaults; the first abandons them.
For the category, see the tool use glossary entry. For the broader picture of how coding agents differ, see the pillar guide: The Complete Guide to Prompting AI Coding Agents.
How v0 Prompting Differs From Full-Stack Generators and In-IDE Agents
It helps to place v0 on the same map as other coding-agent tools. They are not interchangeable, and the prompt shapes differ.
| Dimension | v0 | Full-stack generator (Bolt, Replit Agent) | In-IDE agent (Cursor) |
|---|---|---|---|
| Unit of work | A component or page | An app | An edit |
| Environment | Vercel's hosted preview | A hosted project or sandbox | Your editor |
| Default stack | React + Tailwind + shadcn/ui | Agent's choice (or pinned) | Your existing project |
| Typical prompt | A component brief | A product brief | A targeted ask against real files |
| What "done" looks like | A UI you can see and export | A running app | A merged diff |
| Where iteration happens | Visual refinement | Run-observe-refine on the app | Review of edits |
A v0 prompt is shaped like a component brief, not a PRD and not a code change request. You describe a piece of UI — what it looks like, what it does, what states it handles — and iterate against what you see rendered. For adjacent comparisons, see the Bolt.new prompting guide, the Replit Agent prompting guide, and the Cursor prompting guide.
Component-Level Prompts — The Core Recipe
The biggest lift in v0 prompts is moving from a label to a brief. "A login form" is a label. A brief names behavior, states, props, and visual intent. Five short blocks:
- What the component is. One line. "A settings page nav sidebar for a SaaS dashboard."
- Behavior. What the user does with it — clicks, hovers, keyboard interactions, submits.
- States. The conditions it must render cleanly in — loading, empty, error, populated, disabled, focused. AI-generated UI skips non-happy-path states unless you name them.
- Props or data shape. What it receives. "Takes a list of sections; each section has a label, icon, and active flag." You are not writing TypeScript — you are telling v0 what the data looks like so the component accepts it cleanly.
- Visual intent. The vibe. "Quiet, neutral, lots of whitespace, subtle dividers, no shadows." Or "Playful, rounded, colorful accents, generous padding." v0 will pick something if you do not, and you may not like what it picks.
Skip any of these and v0 fills in a generic default. The whole reason to write a brief is to make the output specific enough to drop into a product that has its own voice.
Screenshot-to-UI — When a Picture Does the Work
v0 accepts images as input. Paste a screenshot — a design mock, a competitor's page, a Figma export, a rough sketch — and it will generate a component that tries to match it. This is the most underused input mode and the one that most changes what counts as a good prompt.
A few things that make screenshot inputs work:
- Crop tightly to the component. A whole-dashboard screenshot forces v0 to guess what you wanted. A cropped shot of the settings sidebar gets you the settings sidebar.
- Pair the image with a short text brief. The image says what it looks like; the text says what it does. "Build it as a reusable component. Include loading and empty states."
- Name what to keep and what to change. "Match the layout and spacing. Replace the colors with neutral grays. Keep the typography weights."
- Expect adaptation, not pixel-perfection. v0 is generating React with Tailwind and shadcn/ui, not reconstructing your HTML. Screenshots work as directional references, not specs.
For rough sketches the bar is low. A whiteboard photo tends to give v0 enough signal for a credible first pass, which is often the point — you are getting out of the blank-canvas phase fast.
The Generate-See-Refine Loop
v0's value is that you can see the component immediately. The first generation is a draft; refinement prompts do most of the design work.
- Generate. Submit the brief. Look at the output; mentally run through the states you asked for.
- See. Identify one or two concrete things to change. "Spacing between items is too tight." "Active state should be a filled background, not a left border." Not ten changes — two.
- Refine. Send a follow-up referencing what you saw. "Increase the spacing between sidebar items. Change the active state to a filled neutral background. Add an empty state."
- Repeat. Two or three tight loops beat one long prompt. Five loops is a sign the brief was wrong — rewrite it rather than piling on refinements.
The discipline is keeping each refinement narrow. v0 applies a handful of changes cleanly; it regresses things when asked to apply fifteen at once. If the fix list gets long, write a new brief from scratch — usually faster than refining your way there.
A Component Brief Example
A hypothetical component brief for v0. The shape is what matters.
COMPONENT
A settings page sidebar for a SaaS dashboard. Reusable.
Left column on desktop; collapses to a top select on mobile.
BEHAVIOR
- Renders a list of sections ("Profile", "Team", "Billing",
"Notifications", "API keys").
- Clicking a section calls onSelect with the section id.
No routing inside the component.
- Current section is visually active.
- Keyboard: up/down moves focus, Enter selects.
STATES
- Populated: shows the section list.
- Loading: skeleton rows matching the item layout.
- Empty: small muted message ("No settings yet").
- Error: small inline error with a retry button.
PROPS (shape — agent picks types)
- sections: array of { id, label, icon, disabled? }
- activeId: currently selected section id
- status: 'loading' | 'ready' | 'empty' | 'error'
- onSelect: called with a section id
- onRetry: called from the error state
VISUAL INTENT
- Quiet and neutral. Lots of whitespace.
- Active state: filled neutral background, bold label.
- Hover: subtle background tint.
- Icons left of the label, same size across items.
- No shadows. Subtle dividers only where needed.
- Dark mode via Tailwind's dark: variants.
OUT OF SCOPE
- Section content panels. Nav only.
- Routing. Parent handles it.
- Animations beyond simple hover transitions.
Every block closes a gap v0 would otherwise fill with a default. The states block does as much work as the behavior block — the difference between a sidebar that looks right in isolation and one that looks right before the data arrives.
When v0 Shines vs. When It Doesn't
The sweet spot is isolated UI: a component to drop into a project, a landing page for tomorrow, a page template for a marketing site, UI for an internal tool without a custom design system. Anywhere the job is "make this surface exist quickly, in a coherent visual style, so we can iterate."
Where v0 is weaker:
- Full applications. v0 generates UI, not backends. For that, see the Bolt.new or Replit Agent guides.
- Backend integration. v0 can generate components that call APIs, but wiring them into a real backend, handling auth, and managing server state is work you do after exporting.
- Long-lived codebases. Dropping v0 output into an existing app with its own conventions and design tokens takes cleanup. An in-IDE agent like Cursor that can read your files is a better fit for that phase.
- Highly custom visual systems. v0 is opinionated about React + Tailwind + shadcn/ui. On a different stack or a bespoke design system, v0 output is a sketch to port.
A rough decision heuristic:
- Isolated component or page, stack-agnostic, want it today. v0 is a strong default.
- Full app with a backend. Use a full-stack generator.
- Targeted change inside an existing repo. Use an in-IDE agent.
- UI that must match a custom design system exactly. Use v0 as a sketch generator, then adapt by hand or with an in-IDE agent.
Common Anti-Patterns
- One-word labels as prompts. "Pricing page." The generator picks layout, structure, tone, and copy voice — none of which you got to steer. Fix: write a brief with behavior, states, and visual intent.
- Fifteen refinements in one follow-up. v0 regresses something every time. Fix: one or two refinements per loop; rewrite the brief if the list gets long.
- Asking for states you do not describe. "Handle all the edge cases" produces empty states that look like error states. Fix: name each state and what it should look like.
- Screenshot without guidance. An image alone leaves v0 guessing whether to copy, adapt, or use as inspiration. Fix: pair the screenshot with a short brief on what to keep and change.
- Fighting the default stack. "Build this without Tailwind." v0 can try, but you lose the thing that makes it coherent. Fix: accept the stack for generation; port after if you need to.
- Treating first output as final. Shipping without refinement leaves the default-ness visible. Fix: plan on two or three loops.
FAQ
How is v0 different from a full-stack generator like Bolt or Replit Agent?
v0 generates UI. Full-stack generators try to produce a running app with a backend and a database. A v0 prompt is a component or page brief; a Bolt or Replit Agent prompt is closer to a one-page product brief. See the Bolt.new prompting guide and Replit Agent prompting guide.
Should I use v0 or an in-IDE agent like Cursor?
Use v0 when the job is generating new UI from a brief. Use an in-IDE agent when the job is changing code inside a codebase that already exists. The tools are complementary: generate with v0, then use Cursor to adapt output to your project's conventions.
Does screenshot-to-UI actually work?
It works well enough to be useful, with the caveats above: crop tightly, pair with a text brief, expect adaptation rather than pixel-perfect cloning. For sketches and rough mocks it is a strong unblock; for production design specs it is a starting point.
Why does the first generation look generic?
Because you probably wrote a label, not a brief. When you do not specify visual intent or states, v0 picks the most neutral option in each slot. Adding a visual-intent block and a states block usually moves output from generic to specific.
Is v0 output production-ready?
It is a strong draft. The generated React is clean, but "production-ready" depends on your design tokens, accessibility standards, data layer, and test coverage. Expect to adapt output to your codebase before shipping. See the pillar guide for how v0 fits into the broader coding-agent landscape.