Building Startup MVPs with Claude Code

Written by Michael Lip · Solo founder of Zovo · $400K+ on Upwork · 100% JSS Join 50+ builders · More at zovo.one

The Problem

You have a startup idea and need to ship an MVP fast. You need authentication, a database, a frontend, payment processing, email, and deployment. Building all of this from scratch takes weeks. You need an AI-powered workflow that lets a solo developer or tiny team ship a production-ready MVP in days, not months.

Quick Start

Tell Claude Code your product idea and let it build the foundation:

I'm building a SaaS tool for freelancers to create and send invoices.
Core features for MVP:
- User auth (email + Google)
- Create/edit/delete invoices
- Add line items with quantities and rates
- Send invoices via email with a unique payment link
- Track invoice status (draft, sent, viewed, paid)
- Stripe payment processing for receiving payments
- Simple dashboard showing outstanding and paid invoices

Tech stack: Next.js 15, TypeScript, Prisma, PostgreSQL, Tailwind CSS, Stripe.
Deploy to Vercel.

Set up the project from scratch with all of these features.
Start with the database schema and authentication.

What Claude Code Brings to MVP Development

Claude Code is the fastest path from idea to working product for several reasons:

  1. Full-stack generation: It writes frontend, backend, database schema, and deployment config
  2. Integration knowledge: It knows how to wire up Stripe, auth providers, email services, and databases
  3. Production patterns: It uses proper error handling, validation, and security from the start
  4. Iteration speed: It can make changes, run tests, and verify in minutes

A solo developer with Claude Code can match the output of a 3-4 person team during the MVP phase.

Step-by-Step Guide

Step 1: Define the MVP scope

Before coding, ask Claude Code to help narrow the scope:

I'm building [product description]. Help me define a ruthless MVP scope:
1. What are the 3-5 features that must exist for launch?
2. What can I defer to v2?
3. What third-party services should I use instead of building?
4. What's the simplest possible tech stack?

Claude Code produces a focused plan:

## MVP Scope (Week 1-2)
Must have:
- Email/password auth (NextAuth.js)
- Invoice CRUD with line items
- PDF generation (react-pdf)
- Stripe payment links
- Dashboard with key metrics

## Defer to v2
- Google OAuth
- Recurring invoices
- Multiple currencies
- Client portal
- Custom branding/templates

## Third-party services
- Auth: NextAuth.js (free, self-hosted)
- Payments: Stripe (industry standard)
- Email: Resend ($0 for first 3,000/month)
- Database: Neon PostgreSQL (free tier)
- Hosting: Vercel (free tier for MVP)
- PDF: @react-pdf/renderer (open source)

Step 2: Scaffold the project

Create a new Next.js 15 project with TypeScript, Tailwind CSS, and Prisma.
Set up the project structure:
- app/ for routes (App Router)
- components/ for reusable UI
- lib/ for utilities and services
- prisma/ for schema and migrations
Include ESLint, Prettier, and a basic CLAUDE.md.

Step 3: Build the database schema

Create the Prisma schema for the invoice app:
- User (auth fields, business info)
- Invoice (number, status, dates, totals, client info)
- InvoiceItem (description, quantity, rate, amount)
- Payment (Stripe payment intent, amount, status)

Include proper indexes, relations, and soft deletes.
Generate the initial migration.

Claude Code generates:

model User {
  id            String    @id @default(cuid())
  email         String    @unique
  passwordHash  String
  businessName  String?
  businessEmail String?
  businessPhone String?
  businessAddress String?
  invoices      Invoice[]
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
}

model Invoice {
  id           String        @id @default(cuid())
  number       String        @unique
  userId       String
  user         User          @relation(fields: [userId], references: [id])
  clientName   String
  clientEmail  String
  status       InvoiceStatus @default(DRAFT)
  items        InvoiceItem[]
  payments     Payment[]
  subtotal     Decimal       @db.Decimal(10, 2)
  taxRate      Decimal       @db.Decimal(5, 2) @default(0)
  taxAmount    Decimal       @db.Decimal(10, 2) @default(0)
  total        Decimal       @db.Decimal(10, 2)
  dueDate      DateTime
  sentAt       DateTime?
  paidAt       DateTime?
  notes        String?
  createdAt    DateTime      @default(now())
  updatedAt    DateTime      @updatedAt

  @@index([userId, status])
  @@index([clientEmail])
  @@index([dueDate])
}

enum InvoiceStatus {
  DRAFT
  SENT
  VIEWED
  PAID
  OVERDUE
  CANCELLED
}

model InvoiceItem {
  id          String  @id @default(cuid())
  invoiceId   String
  invoice     Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
  description String
  quantity    Decimal @db.Decimal(10, 2)
  rate        Decimal @db.Decimal(10, 2)
  amount      Decimal @db.Decimal(10, 2)
  sortOrder   Int     @default(0)
}

model Payment {
  id              String        @id @default(cuid())
  invoiceId       String
  invoice         Invoice       @relation(fields: [invoiceId], references: [id])
  stripePaymentId String        @unique
  amount          Decimal       @db.Decimal(10, 2)
  status          PaymentStatus
  createdAt       DateTime      @default(now())

  @@index([invoiceId])
}

enum PaymentStatus {
  PENDING
  SUCCEEDED
  FAILED
  REFUNDED
}

Step 4: Set up authentication

Set up NextAuth.js with email/password authentication.
Include:
- Registration with email verification
- Login with JWT sessions
- Password hashing with bcrypt
- Protected API routes middleware
- Protected page routes middleware

Step 5: Build the core feature

Build the invoice creation flow:
1. Form page with dynamic line items (add/remove rows)
2. Auto-calculate subtotal, tax, and total as user types
3. Save as draft
4. Preview the invoice
5. Send via email with a unique payment link
6. Server action for CRUD operations with Zod validation

Step 6: Add payment processing

Integrate Stripe for receiving payments:
1. Create a Stripe checkout session when client clicks "Pay Invoice"
2. Handle the webhook for payment_intent.succeeded
3. Update invoice status to PAID when payment completes
4. Send a receipt email to the client
5. Send a notification email to the freelancer
Use Stripe's hosted checkout page (no custom payment form needed for MVP).

Step 7: Build the dashboard

Create a dashboard page showing:
- Total outstanding invoices (count and amount)
- Total paid this month
- Total overdue
- Recent invoices list with status badges
- Quick actions: create invoice, view all invoices
Use server components for data fetching.

Step 8: Deploy

Set up deployment to Vercel:
1. Create vercel.json with build configuration
2. Set up environment variables for Stripe, database, and auth
3. Configure Neon PostgreSQL for production
4. Run prisma migrate deploy in the build step
5. Set up the Stripe webhook endpoint for production
// vercel.json
{
  "buildCommand": "prisma migrate deploy && next build",
  "env": {
    "DATABASE_URL": "@database-url",
    "NEXTAUTH_SECRET": "@nextauth-secret",
    "STRIPE_SECRET_KEY": "@stripe-secret-key",
    "STRIPE_WEBHOOK_SECRET": "@stripe-webhook-secret"
  }
}

Step 9: Iterate based on feedback

After launching the MVP, use Claude Code to rapidly iterate:

Users are asking for PDF download. Add a "Download PDF" button
to the invoice detail page that generates a professional PDF
using @react-pdf/renderer. Match the invoice preview layout.

Claude Code can add features in minutes that would take hours manually.

MVP Checklist

Ask Claude Code to verify launch readiness:

Run through this MVP launch checklist and fix any issues:
- [ ] Authentication works (register, login, logout, protected routes)
- [ ] Core feature works end-to-end (create → send → pay invoice)
- [ ] Error handling on all forms (validation, server errors)
- [ ] Mobile responsive (test at 375px width)
- [ ] Loading states (no blank screens while data loads)
- [ ] 404 page
- [ ] Environment variables are not hardcoded
- [ ] Database migrations run in production
- [ ] Stripe webhook is configured for production
- [ ] Basic SEO (title, description, OG tags on landing page)

Cost Breakdown for MVP

An MVP built with Claude Code and free tiers:

Service Cost
Vercel (hosting) Free tier
Neon PostgreSQL Free tier (0.5 GB)
Stripe 2.9% + $0.30 per transaction
Resend (email) Free (3,000 emails/month)
Claude Code (Max) $100-200/month
Domain ~$12/year
Total ~$112-212/month

**Written by Michael** — solo dev, Da Nang, Vietnam. 50K+ Chrome extension users. $500K+ on Upwork (100% Job Success). Runs 5 Claude Max subs in parallel. Built this site with autonomous agent fleets. [See what I'm building →](https://zovo.one)

I'm a solo developer in Vietnam. 50K Chrome extension users. $500K+ on Upwork. 5 Claude Max subscriptions running agent fleets in parallel. These are my actual CLAUDE.md templates, orchestration configs, and prompts. Not a course. Not theory. The files I copy into every project before I write a line of code. **[See what's inside →](https://zovo.one/lifetime?utm_source=ccg&utm_medium=cta-default&utm_campaign=claude-code-for-startup-mvp-development)** $99 once. Free forever. 47/500 founding spots left.