UIGuides

How to Build with v0

5 min read

Practical guide to using v0 for UI generation. Covers writing effective prompts, iterating in the chat interface, copying to Next.js, and using v0 with Cursor.

v0 is Vercel's AI UI generator. You describe a component or page, it generates React code with Tailwind CSS and shadcn/ui components. The output is real, runnable code — not a mockup.

Used well, it's one of the fastest ways to go from an idea to working UI. Used carelessly, you end up with code you don't understand and can't maintain.

Here's how to use it effectively.

What v0 actually generates

v0 outputs React components using Tailwind CSS for styling and shadcn/ui for component primitives. The code runs in Next.js projects out of the box.

Every response includes:

  • Component code you can copy directly
  • A live preview in the v0 interface
  • The ability to chat and iterate on the result

v0 uses credits — the free tier gives you a limited number of generations per month. Vercel's Pro plan ($20/month) includes significantly more.

Writing effective prompts

The quality of your output is almost entirely determined by your prompt. Vague prompts produce generic output. Specific prompts produce useful output.

Bad prompt: "Build a dashboard"

Better prompt: "Build a SaaS analytics dashboard with a sidebar navigation, a header with user avatar and notification bell, and a main content area with 4 stat cards (total users, active today, MRR, churn rate), followed by a line chart for monthly revenue and a table of recent transactions. Use a clean minimal style with a white background."

The elements of a good v0 prompt:

  • Specific components: Name the UI elements you need (sidebar, modal, dropdown, data table)
  • Layout: Describe the layout structure explicitly
  • Content: Give real-ish example content rather than lorem ipsum placeholders
  • Style direction: "Minimal," "dense," "card-based," "sidebar layout" — style words help
  • Behavior: Mention interactions if they matter ("clicking a row opens a slide-out panel")

Reference real products if they're close to what you want: "Similar to Linear's issue list" or "Like Stripe's dashboard stat cards."

Iterating in the chat interface

After the initial generation, use the chat to refine. You don't need to rewrite your whole prompt — just describe the change.

Good iteration messages:

  • "Make the sidebar collapsible with a toggle button"
  • "Replace the line chart with a bar chart"
  • "Add a search input above the table"
  • "Change the stat cards to use a darker background"

v0 maintains the context of what it built, so you can iterate incrementally. Don't try to change everything at once — make one or two changes per message. You'll get cleaner results and it's easier to undo if something goes wrong.

If v0 goes off in a wrong direction, you can revert to a previous version using the version history in the interface.

Copying to your Next.js project

When you're happy with a component, click "Copy code" and paste it into your project. The code assumes you have Tailwind CSS and shadcn/ui configured.

If you don't have shadcn/ui set up, run npx shadcn@latest init in your project first. Then install specific components that v0 uses — v0 tells you which ones in the code comments or you'll see the import errors when you run the project.

The v0 CLI (npm install -g vercel) lets you add components directly from v0 to your project without manual copying. Run v0 add [component-url] and it adds the code automatically.

Using v0 with Cursor for further customization

The practical workflow: generate the scaffold in v0, then refine it in Cursor.

v0 is good at initial generation. Cursor is better at iterating within an existing codebase because it can reference your other files, understand your component patterns, and maintain consistency with your design system.

After copying v0 code into your project, open it in Cursor and use Cursor Chat to make more targeted changes: "Update this component to use the Button component from our design system at @/components/ui/button" or "Add TypeScript types for the transaction data."

Refine v0 code in Cursor

When v0 is faster than writing from scratch

v0 is genuinely faster in these situations:

  • Scaffolding a new page layout from a rough description
  • Generating a data table with sorting and filtering
  • Building a form with validation UI
  • Creating a settings page structure
  • Generating a pricing table layout

In these cases, v0 saves 30-60 minutes of boilerplate setup. The output needs cleanup and refinement, but the structure is sound.

When v0 isn't the right tool

Complex state management. v0 generates UI well but doesn't know your data model. If the component needs to connect to your API, handle complex state, or integrate with your auth system, you'll spend as much time adapting v0's output as writing it yourself.

Matching an existing design system. v0 defaults to shadcn/ui components. If your design system uses different primitives, you'll need to swap everything out. For projects with a well-established component library, writing components that use your primitives directly is faster.

Learning React. If you're new to React, over-relying on v0 means you're accumulating code you don't understand. You won't be able to debug it effectively or extend it when requirements change.

Good vs bad v0 prompt examples

Bad: "Make a user profile page" Good: "Build a user profile page with a header showing the user's avatar, name, and role. Below that, a two-column layout with contact information on the left and a recent activity feed on the right. Include an Edit Profile button in the header."

Bad: "Add a table" Good: "Add a data table showing invoices with columns for Invoice ID, Client, Date, Amount, and Status. Status should be a colored badge (green for paid, yellow for pending, red for overdue). Include a search input above the table that filters by client name."

Start generating UI with v0

The more specific you are, the less iteration you need. Spending 3 minutes writing a detailed prompt saves 20 minutes of back-and-forth refining a vague output.