v0.dev is Vercel's AI-powered UI generator. You describe a React component in plain English and it spits out production-quality code built on Shadcn/UI and Tailwind. If you've spent hours copying component patterns from docs, adjusting padding in dev tools, or asking AI for the nth iteration of a pricing table, v0 cuts that time dramatically.
But the quality gap between a well-crafted v0 prompt and a lazy one is wide. Here's what actually works.
The fundamental v0 prompting model
v0 generates one component at a time. It's not a full-stack tool — no database, no API routes, no auth. Everything it produces is a React component (or set of components) that you drop into your project.
That constraint shapes how you prompt. You're writing a spec for a UI component, not an application.
The structure that works consistently:
Build a [component type] that [primary function].
Layout: [describe the layout]
Content: [what data/text should appear]
Interactions: [user actions and their effects]
Style: [visual tone, specific constraints]
Real example:
Build a pricing table component with three tiers.
Layout: three equal-width cards in a row, responsive to single column on mobile.
Content: Free ($0), Pro ($29/mo), Enterprise (custom pricing). Each card has a tier name, price, 5 feature bullets, and a CTA button.
Interactions: clicking any CTA button should call an onSelect(tier) prop.
Style: highlight the Pro tier with a border accent and a "Most popular" badge. Use muted colors for Free, vibrant for Pro.
This produces something you could actually ship. The vague version ("make a pricing table") produces something generic that needs 4 more iterations.
Component types v0 is best at
v0 excels at:
- Data display components: tables, cards, stats grids, chart containers (not the charts themselves)
- Form components: multi-step forms, settings panels, filter sidebars
- Navigation components: sidebars, tabbed interfaces, breadcrumbs
- Marketing components: hero sections, feature grids, testimonial layouts, pricing tables
- Dashboard layouts: metric cards, activity feeds, status panels
It's weaker at:
- Animated components (the code generates but often needs manual tweaking)
- Complex data visualization (use a charting library and have v0 generate the wrapper)
- Anything requiring real data fetching (it generates mock data — you connect the real source)
Iteration techniques
v0's real power is in iteration. The first output is rarely the final one.
Stack iterations in one message. Instead of "make the button blue" followed by "make the text smaller", bundle them: "Make the CTA button blue. Reduce the feature bullet font size to 13px. Add a checkmark icon before each bullet."
Reference what's working. "Keep the card layout exactly as-is but change the color scheme to..." prevents v0 from restructuring things you like.
Ask for variants. "Generate three variations of this header: one with an image on the right, one centered with no image, one with a dark background." Evaluate them and continue from the strongest.
Extract and isolate. If a complex component has a sub-element you want to improve, describe just that element: "Take the pricing card header (the part with tier name and price) and redesign it to feel more premium."
Exporting to Next.js
v0 generates code in the context of Shadcn/UI and Tailwind — which is the default stack for Next.js projects. Pasting into a fresh Next.js project with Shadcn installed usually works with minimal adjustments.
Things to check on export:
- Import paths: v0 uses
@/components/ui/...by default, which matches the standard Shadcn setup. If your project uses a different path alias, do a global find-replace. - Mock data: v0 often generates components with hardcoded data. Replace with your actual data source.
- Prop types: v0's TypeScript types are generally solid but check them before trusting them in a typed codebase.
If you're using the v0 CLI (npx v0), you can install components directly into your project without copy-pasting. Run npx v0 add [component-url] and it handles the import structure automatically.
Prompting for specific design systems
If you're not using Shadcn defaults, be explicit:
Build this using only standard HTML elements and Tailwind classes. No Shadcn components.
or:
Build this component to match the style of Shadcn/UI but using our custom token variables instead of the Shadcn tokens. Primary color is --brand-500, background is --surface-100.
v0 can adapt to non-default design systems, but it needs explicit direction. Leaving this unspecified means it defaults to Shadcn, which might clash with your existing setup.
Using v0 with an existing codebase
The most underrated use case: pasting in your existing component and asking v0 to improve or extend it.
Here's my existing sidebar component:
[paste your code]
Extend it to:
- Add a collapsible section for "Settings" with three sub-items
- Add a notification badge on the "Inbox" item that accepts a count prop
- Ensure it degrades gracefully on mobile (hide labels, show only icons)
This is significantly more effective than describing everything from scratch, because v0 can match your existing patterns and naming conventions.
Common mistakes
Too vague on layout: "make it look nice" gives you something, but "three columns on desktop, stack vertically on mobile" gives you something useful.
Forgetting responsive behavior: v0 doesn't always assume mobile-first. Specify "responsive" or describe the mobile layout explicitly.
Ignoring the prompt input field on iteration: Each new iteration message is a full instruction to v0. Don't just type "change the button". Type the full description of what you want changed and what should stay the same.
Not specifying state: If a component needs to track user interaction (accordion open/closed, tab selected, form submitted), say so explicitly. v0 won't add state management unless you ask.
For building full applications rather than individual components, see our Lovable vs Bolt vs v0 comparison — v0 is one piece of a larger workflow.



