v0.dev Usage Guide for TVL Platform
Using Vercel's v0.dev AI to accelerate MVP.0 development while maintaining ADR compliance
Summary
This guide shows how to use v0.dev to generate UI components for TVL Platform's admin dashboard (MVP.0) while ensuring consistency with our architectural decisions (ADRs).
Purpose: Accelerate MVP.0 development (4-5 weeks → 1 week) without compromising code quality.
When to use: MVP.0 only (Weeks 1-10), before design team is hired.
When to stop: MVP.1+ when professional UX designer creates custom design system.
Table of Contents
- Why v0.dev for MVP.0
- v0.dev + ADR Alignment
- Prompt Templates
- Code Review Checklist
- Migration Strategy
- Best Practices
- FAQ
Why v0.dev for MVP.0
✅ Perfect Stack Alignment
v0.dev generates code using exactly our tech stack:
| Technology | Our ADR | v0.dev Default | Alignment | 
|---|---|---|---|
| React | ADR-0015 (React 18) | React 18 | ✅ Perfect | 
| Next.js | ADR-0016 (Next.js 14 App Router) | Next.js 14 App Router | ✅ Perfect | 
| Tailwind | ADR-0017 (Tailwind CSS) | Tailwind CSS | ✅ Perfect | 
| Shadcn UI | ADR-0018 (Shadcn UI) | Shadcn UI components | ✅ Perfect | 
| TypeScript | ADR-0005 (TS strict mode) | TypeScript | ✅ Perfect | 
Result: v0.dev output requires minimal changes to match our ADRs.
✅ Speed Advantage
| Task | Manual | With v0.dev | Savings | 
|---|---|---|---|
| Dashboard layout | 2 days | 10 min | 95% faster | 
| Property list table | 1 day | 10 min | 95% faster | 
| Booking calendar | 3 days | 20 min | 95% faster | 
| Forms | 1 day each | 10 min each | 95% faster | 
| Total MVP.0 UI | 3-4 weeks | 1 week | 75% faster | 
✅ Quality Output
v0.dev generates:
- ✅ Accessible components (WCAG 2.1 AA)
- ✅ Responsive layouts (mobile, tablet, desktop)
- ✅ TypeScript types
- ✅ Production-ready code
- ✅ Modern React patterns (hooks, Server Components)
v0.dev + ADR Alignment
How v0.dev Aligns with Our ADRs:
ADR-0015: React 18 ✅
v0.dev uses:
- React 18.x (latest)
- Client Components ('use client')
- Server Components (when appropriate)
- Modern hooks (useState, useEffect, useCallback)
No changes needed.
ADR-0016: Next.js 14 App Router ✅
v0.dev generates:
- App Router structure (app/directory)
- Server Components by default
- Client Components with 'use client'directive
- Route groups and layouts
No changes needed.
ADR-0017: Tailwind CSS ✅
v0.dev uses:
- Tailwind utility classes
- Responsive modifiers (sm:,md:,lg:)
- Dark mode support (dark:)
- Custom color palette (can customize in prompts)
No changes needed.
ADR-0018: Shadcn UI ✅
v0.dev uses Shadcn UI components:
- Button, Input, Select, Checkbox, etc.
- Dialog, Dropdown, Popover, Toast
- Table, Card, Badge, Avatar
- All components are imported from @/components/ui/
No changes needed.
ADR-0019: Zustand ⚠️ Requires Customization
Problem: v0.dev doesn't know about Zustand by default.
Solution: Add Zustand instructions to prompts:
For state management, use Zustand instead of React Context.
Example:
import { create } from 'zustand';
export const usePropertyStore = create((set) => ({
  properties: [],
  setProperties: (properties) => set({ properties }),
}));
When to use Zustand:
- Global state (current organization, user session)
- Complex state (property list filters, pagination)
When NOT to use Zustand:
- Simple component state (use useState)
- Server state (use TanStack Query)
ADR-0020: TanStack Query ⚠️ Requires Customization
Problem: v0.dev generates mock data, not real API calls.
Solution: Replace mock data with TanStack Query:
v0.dev generates:
const [properties, setProperties] = useState([
  { id: 1, name: "Beach House" },
  { id: 2, name: "Mountain Cabin" }
]);
Replace with TanStack Query:
import { useQuery } from '@tanstack/react-query';
const { data: properties, isLoading } = useQuery({
  queryKey: ['properties'],
  queryFn: async () => {
    const res = await fetch('/api/v1/properties');
    return res.json();
  }
});
This change is required for all data fetching.
ADR-0021: React Hook Form + Zod ⚠️ Requires Customization
Problem: v0.dev generates basic forms without validation.
Solution: Add Zod validation to prompts:
For forms, use React Hook Form with Zod validation.
Example:
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
const schema = z.object({
  name: z.string().min(1, "Name is required"),
  email: z.string().email("Invalid email"),
});
const form = useForm({
  resolver: zodResolver(schema),
});
This change is required for all forms.
Prompt Templates
Template 1: Dashboard Page
Create a Next.js 14 App Router dashboard page using Shadcn UI components.
Requirements:
- 4 metric cards at the top (Total Properties, Active Bookings, Revenue, Occupancy)
- Recent bookings table below (5 rows, columns: Guest, Property, Dates, Status, Actions)
- Use Shadcn UI Card, Table, Badge, Button components
- Responsive layout (stack cards on mobile)
- TypeScript with strict types
- Use 'use client' directive
Color scheme:
- Primary: Blue (Tailwind blue-600)
- Success: Green (Tailwind green-600)
- Danger: Red (Tailwind red-600)
The data should be fetched from an API (use placeholder for now).
Template 2: Data Table with Filters
Create a properties list page using Shadcn UI Table and filters.
Requirements:
- Table with columns: Property Name, Location, Units, Status, Actions
- Filters: Search by name, Status dropdown (Active/Inactive), Property Type dropdown
- Pagination (10 rows per page)
- Bulk actions: Select multiple, Activate/Deactivate, Export CSV
- Responsive (switch to cards on mobile)
- TypeScript
- Use Shadcn UI Table, Input, Select, Checkbox, Button components
Actions column should have: Edit (pencil icon), Delete (trash icon)
Use placeholder data for now (will connect to API later).
Template 3: Form with Validation
Create a property creation form using React Hook Form and Zod validation.
Fields:
- Property Name (required, min 3 chars)
- Description (required, min 10 chars)
- Address (required)
- City (required)
- State (dropdown, US states)
- Property Type (dropdown: House, Apartment, Villa)
- Units Count (number, min 1)
Requirements:
- Multi-step form (3 steps: Basic Info, Location, Units)
- Zod schema for validation
- React Hook Form with zodResolver
- Shadcn UI Form components (Input, Select, Textarea, Button)
- Show validation errors inline
- Stepper component at top
- TypeScript
On submit, log form data to console (will connect to API later).
Template 4: Modal/Dialog
Create a booking details modal using Shadcn UI Dialog.
Requirements:
- Opens when clicking "View Details" button in table
- Shows booking information:
  - Guest Name
  - Property Name
  - Check-in / Check-out dates
  - Total Price
  - Status (badge)
  - Created At
- Actions: Edit, Cancel Booking (confirmation dialog), Close
- Shadcn UI Dialog, Button, Badge components
- TypeScript
- Responsive
Use placeholder booking data.
Code Review Checklist
After generating code with v0.dev, review against these criteria:
1. ADR Compliance
- Uses React 18 patterns (no class components)
-  Next.js 14 App Router (app/directory)
- Tailwind CSS only (no inline styles, no CSS modules)
-  Shadcn UI components (imported from @/components/ui/)
-  TypeScript with types (no anytypes)
-  Client Component directive when needed ('use client')
2. Replace Mock Data with TanStack Query
- Remove hardcoded data arrays
-  Add useQueryfor data fetching
-  Add loading states (isLoading,isPending)
-  Add error handling (isError,error)
-  Add query keys following pattern: ['resource', id, filters]
3. Add Form Validation (if forms)
- Replace basic forms with React Hook Form
- Add Zod schema for validation
-  Use zodResolverinuseForm
- Show validation errors inline
4. Multi-Tenancy
-  Add org_idto API calls (context or Zustand store)
- Filter data by organization
- Ensure RLS policies are enforced (backend responsibility)
5. Accessibility
- Keyboard navigation works
-  Screen reader labels (aria-label,aria-describedby)
- Color contrast meets WCAG AA
- Focus indicators visible
6. Error Handling
-  API errors shown to user (use toastfrom Shadcn UI)
- Network errors handled gracefully
- Form errors displayed clearly
- Error boundaries for component errors (React 18)
7. Code Quality
- No console.logs (use proper logging)
- No commented-out code
- Meaningful variable names
- Components under 200 lines (split if larger)
- TypeScript strict mode compliant
Migration Strategy (MVP.0 → MVP.1)
Phase 1: MVP.0 (Weeks 1-10) - Use v0.dev
Goal: Functional UI fast, without custom design
Process:
- Generate components with v0.dev
- Review against checklist
- Replace mock data with TanStack Query
- Add form validation (Zod)
- Test and ship
Result: Admin dashboard that works, looks professional (Shadcn defaults)
Phase 2: MVP.1 (Weeks 11-16) - Migrate to Design System
Goal: Replace v0.dev components with custom-designed components
Process:
- Designer creates design system (colors, typography, custom components)
- Identify components to replace:
- Keep: Generic Shadcn components (Button, Input, Table)
- Replace: Custom components (PropertyCard, BookingCalendar, DashboardMetric)
 
- Gradual migration:
- Replace one screen at a time
- Start with high-traffic pages (dashboard)
- Test thoroughly
 
Example Migration:
Before (v0.dev generated):
<Card>
  <CardHeader>Total Properties</CardHeader>
  <CardContent>{properties.length}</CardContent>
</Card>
After (custom design):
<MetricCard
  title="Total Properties"
  value={properties.length}
  trend={+12}
  icon={<HomeIcon />}
/>
Best Practices
1. Use v0.dev for Layouts, Not Logic
✅ Good use cases:
- Dashboard layouts
- Table structures
- Form layouts
- Modal designs
- Card grids
❌ Bad use cases:
- Business logic
- API integration
- State management
- Authentication flows
- Complex algorithms
Rule: v0.dev generates UI shell, you add the brains.
2. Generate One Component at a Time
Don't ask v0.dev to generate entire app:
- ❌ "Create a complete property management dashboard"
- ✅ "Create a property list table component"
Why: Smaller prompts = better results, easier to review.
3. Be Specific in Prompts
Vague prompt:
Create a dashboard
Specific prompt:
Create a Next.js 14 dashboard page with:
- 4 metric cards (properties, bookings, revenue, occupancy)
- Shadcn UI Card components
- Responsive grid (2 columns mobile, 4 columns desktop)
- TypeScript
- Use 'use client'
Result: Specific prompts = better output, less rework.
4. Iterate in v0.dev, Then Export
Workflow:
- Generate component in v0.dev
- Use v0.dev's iteration feature (refine with chat)
- Get it 80% right in v0.dev
- Export to codebase
- Finish last 20% manually (API integration, validation)
Don't: Generate → export → manually fix everything
5. Document What Was v0.dev Generated
Add comment to files:
/**
 * Property List Table
 *
 * Generated with v0.dev on 2025-01-26
 * Prompt: "Property list table with filters and pagination"
 * Modified: Added TanStack Query, Zod validation
 *
 * TODO: Replace with custom design in MVP.1
 */
Why: Team knows which components are temporary (v0.dev) vs permanent (custom design).
FAQ
Q: Is v0.dev output production-ready?
A: 80% yes, 20% requires customization:
✅ Production-ready:
- Component structure
- Responsive layouts
- Accessibility basics
- TypeScript types
⚠️ Requires customization:
- API integration (replace mock data)
- Form validation (add Zod)
- State management (add Zustand/TanStack Query)
- Error handling
- Multi-tenancy (org_id filtering)
Q: Does v0.dev cost money?
A: Yes, but cheap:
- Free: 200 generations/month
- Paid: $20/month for unlimited (Vercel Pro)
Recommendation: Start free, upgrade if needed.
Q: Can v0.dev replace a designer?
A: No, absolutely not.
v0.dev is for:
- ✅ Rapid prototyping (MVP.0)
- ✅ Getting something functional fast
- ✅ Testing ideas
Designers are for:
- ✅ User research
- ✅ Brand identity
- ✅ Custom design systems
- ✅ Conversion optimization
- ✅ Accessibility beyond basics
- ✅ User testing
Strategy: v0.dev for MVP.0, designer for MVP.1+
Q: What if v0.dev generates bad code?
A: Iterate in v0.dev first:
- Use chat to refine - "Make the table responsive"
- Regenerate - Try different prompts
- Mix and match - Take parts from different generations
- Manual fix - If iteration doesn't work, fix manually
If consistently bad: Your prompts need improvement (be more specific).
Q: Should I commit v0.dev code to git?
A: Yes, but:
- Review first (use checklist)
- Customize (add API integration, validation)
- Test (ensure it works)
- Document (add comment it's v0.dev generated)
- Commit
Don't: Copy-paste v0.dev output directly to codebase without review.
Q: How do I handle updates to Shadcn UI?
A: v0.dev uses latest Shadcn UI, so updates are automatic.
If Shadcn releases new component (e.g., Carousel), just ask v0.dev:
Use the new Shadcn Carousel component for the property image gallery
Q: Can v0.dev generate backend code?
A: No, v0.dev is frontend-only (React/Next.js).
For backend (Fastify API, database, etc.), write manually following:
When to Stop Using v0.dev
Stop after MVP.0 (Week 10)
Reasons:
- Designer hired - Professional design system available
- User feedback - Know what actually matters to users
- Brand identity - Need custom design, not generic Shadcn
- Conversion optimization - Designer can A/B test, optimize flows
- Code ownership - Team understands custom components better
Exception: Can still use v0.dev for rapid prototyping/testing ideas.
Example Workflow
Building Property List Page:
Step 1: Generate with v0.dev
Prompt:
Create a Next.js 14 property list page with:
- Table: Property Name, Location, Units, Status, Actions
- Filters: Search, Status dropdown, Property Type dropdown
- Pagination
- Shadcn UI components
- TypeScript
Step 2: Export Code
Copy generated code to /app/properties/page.tsx
Step 3: Review (Checklist)
- ✅ Shadcn components used
- ✅ TypeScript types present
- ✅ Responsive layout
- ⚠️ Mock data needs replacement
- ⚠️ No loading/error states
Step 4: Add TanStack Query
const { data: properties, isLoading, isError } = useQuery({
  queryKey: ['properties', filters],
  queryFn: async () => {
    const res = await fetch(`/api/v1/properties?${new URLSearchParams(filters)}`);
    if (!res.ok) throw new Error('Failed to fetch properties');
    return res.json();
  }
});
if (isLoading) return <LoadingSpinner />;
if (isError) return <ErrorMessage />;
Step 5: Add Multi-Tenancy
const { orgId } = useAuth(); // From Zustand store
const { data: properties } = useQuery({
  queryKey: ['properties', orgId, filters],
  queryFn: async () => {
    const res = await fetch(`/api/v1/properties`, {
      headers: {
        'X-Organization-Id': orgId, // RLS context
      }
    });
    return res.json();
  }
});
Step 6: Test
- Loads data from API
- Filters work
- Pagination works
- Actions (edit, delete) work
- Responsive on mobile
- Keyboard navigation works
Step 7: Commit
git add app/properties/page.tsx
git commit -m "Add property list page (generated with v0.dev, customized with TanStack Query)"
Summary
✅ Use v0.dev for MVP.0 because:
- Aligns perfectly with our stack (React 18, Next.js 14, Shadcn UI, Tailwind)
- Saves 3-4 weeks of development time
- Produces production-ready code (with minor customizations)
- Allows focus on backend/API development
- Good enough for MVP.0 (before users, before designer)
⚠️ Customize v0.dev output:
- Replace mock data with TanStack Query
- Add form validation (Zod)
- Add state management (Zustand for global state)
- Add multi-tenancy (org_id filtering)
- Add error handling and loading states
🎯 Stop using v0.dev after MVP.0:
- Hire designer before MVP.1 (Week 10)
- Designer creates custom design system
- Gradually migrate v0.dev components to custom components
- Keep generic Shadcn components (Button, Input, etc.)
📋 Always:
- Use the prompt templates
- Follow the code review checklist
- Document what was v0.dev generated
- Test before committing
Related Documentation
- UI Specifications - What UI to build (design team)
- ADR-0015: React 18
- ADR-0016: Next.js 14
- ADR-0017: Tailwind CSS
- ADR-0018: Shadcn UI
- ADR-0019: Zustand
- ADR-0020: TanStack Query
- ADR-0021: React Hook Form
Last Updated: 2025-01-26 Maintained By: Frontend Team Status: Active for MVP.0, deprecated after MVP.1