How to Build a Full-Stack App with Claude Code: From Zero to Deploy

Step-by-step tutorial on building a complete full-stack application using Claude Code as your AI pair programmer — from project setup through database, API, frontend, and deployment.

·15 min read

Overview

Can you build a complete full-stack application using an AI coding agent? Yes — and this guide shows you exactly how.

By the end of this tutorial, you'll have built a full-stack SaaS starter app with:

- Frontend: Next.js 14 (App Router) + Tailwind CSS - Backend: Next.js API routes + Prisma ORM - Database: PostgreSQL (via Prisma) - Auth: NextAuth.js with GitHub + email magic links - Payments: Stripe Checkout subscription - Deployment: Vercel

Estimated time: 2-3 hours with Claude Code (vs. 8-12 hours hand-coded).

---

Prerequisites

# What you need installed:
node --version      # v18+
npm --version       # v9+
git --version       # v2.30+

# Claude Code installed claude --version # Should show a version

# A project directory mkdir my-saas-app && cd my-saas-app git init

---

Phase 1: Project Scaffolding (15 Minutes)

Step 1: Set Up the Next.js Project

Instead of manually running create-next-app, let Claude handle it:

Create a Next.js 14 project with:
- App Router
- TypeScript
- Tailwind CSS
- A clean project structure

Run: npx create-next-app@latest . --typescript --tailwind --app --src-dir --import-alias "@/*"

After the scaffolding, set up CLAUDE.md:

# .claude/CLAUDE.md

Project

SaaS starter with Next.js 14, Prisma, Stripe, NextAuth.js

Conventions

- All source in src/ - Pages in src/app/ - Components in src/components/ - API routes: src/app/api/ - Prisma schema: prisma/schema.prisma - Named exports for components - TypeScript strict mode

Step 2: Install Dependencies

Install these dependencies:
- prisma @prisma/client (database ORM)
- next-auth @auth/prisma-adapter (authentication)
- @stripe/stripe-js @stripe/react-stripe-js (payment client)
- stripe (payment server)
- bcryptjs (password hashing)
- zod (validation)

Install dev dependencies: - @types/bcryptjs - prisma

Use npm install for all.

---

Phase 2: Database Setup (20 Minutes)

Step 3: Define the Prisma Schema

Create a Prisma schema with these models:

1. User (from NextAuth) 2. Account (from NextAuth) 3. Session (from NextAuth) 4. VerificationToken (from NextAuth) 5. Subscription: - id (string, @id @default(cuid())) - userId (string, unique) - stripeSubscriptionId (string, unique) - stripePriceId (string) - status (string: active/canceled/past_due/trialing) - currentPeriodEnd (DateTime) - createdAt (DateTime) - updatedAt (DateTime) - Relation to User

Use PostgreSQL provider. Add proper relations and indexes. Then run: npx prisma migrate dev --name init

> External Links: > - Prisma Schema Reference > - NextAuth Prisma Adapter

---

Phase 3: Authentication (30 Minutes)

Step 4: Set Up NextAuth.js

Configure NextAuth.js with:
1. GitHub OAuth provider (requires GITHUB_ID, GITHUB_SECRET env vars)
2. Email magic link provider (requires EMAIL_FROM, EMAIL_SERVER env vars)
3. Prisma adapter for database sessions
4. JWT strategy for sessions
5. Callbacks to add user role to session
6. Sign-in and sign-out pages

Create: - src/app/api/auth/[...nextauth]/route.ts - src/app/api/auth/route.ts (config) - src/lib/auth.ts

Use environment variables model.

External Links: - NextAuth.js Documentation - GitHub OAuth App Setup

Step 5: Create Auth UI Components

Create these components:

1. LoginPage (src/app/login/page.tsx): - Sign in with GitHub button - Email magic link form - Clean Tailwind design

2. AuthStatus (src/components/AuthStatus.tsx): - Shows user avatar and name when logged in - Sign out button - Shows "Sign In" link when logged out

3. SessionProvider wrapper in layout.tsx

---

Phase 4: Payment Integration (30 Minutes)

Step 6: Stripe Checkout

Create Stripe integration:

1. src/lib/stripe.ts: - Stripe server-side client - Stripe client-side promise

2. src/app/api/stripe/create-checkout/route.ts: - POST endpoint - Takes priceId and userId - Creates Stripe Checkout Session - Creates/updates Subscription record on success

3. src/app/api/stripe/webhook/route.ts: - POST endpoint for Stripe webhooks - Handle checkout.session.completed - Handle customer.subscription.updated - Handle invoice.payment_succeeded/failed - Verify webhook signature

4. Pricing page (src/app/pricing/page.tsx): - Monthly/Annual toggle - 3 pricing tiers (Free/Pro/Enterprise) - Checkout button that creates session

External Links: - Stripe Checkout Documentation - Stripe Webhook Events - Stripe Dashboard

---

Phase 5: Frontend Pages (30 Minutes)

Step 7: Build the Core Pages

Create these pages:

1. Landing page (src/app/page.tsx): - Hero section with headline and CTA - Feature grid (3-4 features) - Pricing section - Responsive design with Tailwind

2. Dashboard (src/app/dashboard/page.tsx): - Protected route (redirect if not logged in) - Show user subscription status - Quick stats (if applicable) - Navigation sidebar

3. Settings (src/app/settings/page.tsx): - Profile info display - Subscription management (cancel/upgrade) - Portal link to Stripe Customer Portal

4. Blog (from earlier articles) - list and detail pages

---

Phase 6: Testing & Validation (20 Minutes)

Step 8: Verify Everything Works

Ask Claude to run through a checklist:

Check the following:
1. npm run build — no TypeScript errors
2. npm run lint — no lint errors
3. All page components render without crashing
4. Auth flow: sign in → redirect to dashboard
5. API routes return correct responses
6. Stripe webhook endpoint is accessible

npm run build
# Fix any TypeScript or ESLint errors

> 💡 Pro tip: Ask Claude to fix errors iteratively: >

> @tsconfig.json @.eslintrc.json — The build has these errors: [paste errors]. Fix them.
> 

---

Phase 7: Deployment (15 Minutes)

Step 9: Deploy to Vercel

Set up deployment:

1. Create a Vercel project via CLI: npx vercel --prod

2. Set environment variables in Vercel dashboard: - DATABASE_URL (production PostgreSQL) - NEXTAUTH_SECRET (generate with openssl rand -base64 32) - NEXTAUTH_URL (your production URL) - GITHUB_ID, GITHUB_SECRET - STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET - NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY

3. Run Prisma migrations on production: npx prisma migrate deploy

4. Configure Stripe webhook to point to: https://your-app.vercel.app/api/stripe/webhook

External Links: - Vercel Deployment Docs - Vercel Environment Variables - Stripe Webhook Configuration

---

Claude Code Prompt Templates

Use these prompt templates during each phase:

For Adding Features

Add [feature] to [file]:
- It should [behavior]
- Use [pattern/library]
- Handle errors by [error handling strategy]
- Style with Tailwind using [design pattern]

For Debugging

@[file] — This code has an issue: [describe symptom].
Debug it by:
1. Checking the input types
2. Tracing the data flow
3. Verifying error handling
4. Suggesting a fix

For Code Review

@[file] — Review this code for:
1. TypeScript type safety
2. Error boundary coverage
3. Performance issues
4. Security vulnerabilities (XSS, CSRF, injection)
5. Accessibility (ARIA labels, keyboard nav)
6. Suggest improvements

---

Complete Architecture Diagram

┌──────────────────────────────────────────┐
│              Vercel (Hosting)             │
│                                          │
│   ┌─────────────┐  ┌──────────────┐     │
│   │  Next.js     │  │  API Routes  │     │
│   │  App Router  │──►  (/api/*)    │     │
│   │  Pages       │  │              │     │
│   └──────┬───────┘  └──────┬───────┘     │
│          │                 │             │
│   ┌──────▼─────────────────▼───────┐     │
│   │      NextAuth.js (Auth)        │     │
│   └──────────────┬─────────────────┘     │
│                  │                       │
│   ┌──────────────▼─────────────────┐     │
│   │      Prisma (ORM)              │     │
│   └──────────────┬─────────────────┘     │
└──────────────────┼───────────────────────┘
                   │
        ┌──────────▼──────────┐
        │   PostgreSQL (DB)    │
        │   (Railway/Neon)     │
        └─────────────────────┘

┌────────────────┐ │ Stripe │◄──── Webhook │ Payments │ └────────────────┘

┌────────────────┐ │ GitHub OAuth │ └────────────────┘

---

Time Savings vs. Manual Development

| Phase | Manual Time | With Claude Code | Savings | |-------|------------|-----------------|---------| | Scaffolding | 30 min | 15 min | 50% | | Database schema | 1 hr | 20 min | 67% | | Auth setup | 2 hrs | 30 min | 75% | | Payment integration | 3 hrs | 30 min | 83% | | Frontend pages | 3 hrs | 1 hr | 67% | | Testing & fixes | 2 hrs | 20 min | 83% | | Deployment | 30 min | 15 min | 50% | | Total | 12 hrs | 3 hrs | 75% |

---

Common Pitfalls

🚩 Letting Claude Run Wild

❌ "Build my entire app"
✅ "Create the Prisma schema for users and subscriptions"

Break it down. Claude works best with focused, sequential tasks.

🚩 Not Checking Output

Always verify what Claude created:

git diff  # See all changes
cat src/app/page.tsx | head -20  # Check file content
npm run build  # Verify it compiles

🚩 Over-Engineering

Claude loves abstractions. If it creates 5 files for what should be 1, ask it to simplify:

Simplify this — merge error-handler.ts, logger.ts, and types.ts into a single utils.ts

🚩 Environment Variables

Claude can't set up external services for you. You'll need to: 1. Create a GitHub OAuth App 2. Get Stripe API keys 3. Set up a PostgreSQL database (or use Railway, Supabase) 4. Configure Vercel project

---

Next Steps

After building the starter app:

1. Add your features — Claude can iterate on the scaffold 2. Write tests — Ask Claude: Add Jest tests for all API routes 3. SEO optimizationAdd meta descriptions and OpenGraph tags to all pages 4. AnalyticsAdd Plausible or PostHog analytics 5. Blog — Reference the articles already in this site!

Related Articles: - Best AI Coding Tools 2026 — compare Claude Code with alternatives - Claude Code vs Cursor — choose the right AI coding tool - How to Debug AI-Generated Code — fix issues in your full-stack app - Multi-Agent Coding Workflow Setup — advanced workflow for larger teams

Ad Unit Placeholder

Related Articles