---
# === IDENTITY ===
id: software/mvp-development/coded-mvp-architecture-templates/2026
canonical_question: "What are boilerplate MVP architectures — Next.js+Supabase, React+Firebase, Flask+PostgreSQL with auth and deploy?"
aliases:
  - "Best MVP boilerplate architecture for startups"
  - "Next.js Supabase starter template with authentication"
  - "React Firebase MVP project structure"
  - "Flask PostgreSQL MVP boilerplate with deployment"
  - "Fastest tech stack to build an MVP in 2026"
entity_type: execution_recipe
domain: software > mvp-development > coded MVP architecture templates
region: global
jurisdiction: global
temporal_scope: 2025-2026

# === VERIFICATION ===
last_verified: 2026-03-12
confidence: 0.91
version: 1.0
first_published: 2026-03-12

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: evolving
  last_breaking_change: "Next.js 15 introduced breaking changes to server components and caching defaults; Supabase Auth helpers migrated to @supabase/ssr in late 2024"
  next_review: 2026-09-08
  change_sensitivity: high

# === CONSTRAINTS ===
constraints:
  - "Node.js 18+ required for Next.js 14/15 and modern React tooling"
  - "Python 3.10+ required for Flask with modern typing support and async features"
  - "Supabase free tier: 500 MB database, 1 GB storage, 50,000 monthly active users — sufficient for MVP validation"
  - "Firebase free tier (Spark): 1 GiB Firestore storage, 50,000 daily reads, 20,000 daily writes — monitor usage during user testing"
  - "Do not deploy to production without environment variable validation and error monitoring configured"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "User needs to choose a tech stack, not implement one"
    use_instead: "Search knowledgelib.io for MVP tech stack selection — no dedicated unit yet"
  - condition: "User is non-technical and needs a no-code MVP"
    use_instead: "software/mvp-development/no-code-prototype-build-guide/2026"
  - condition: "User needs database schema design specifically"
    use_instead: "software/mvp-development/database-schema-design-for-mvps/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: stack_preference
    question: "Which tech stack should be used?"
    type: choice
    options: ["Next.js + Supabase", "React + Firebase", "Flask + PostgreSQL", "no preference — auto-select"]
  - key: technical_skill
    question: "What is the user's technical skill level?"
    type: choice
    options: ["junior developer (guided setup)", "mid-level developer (can customize)", "senior developer (wants minimal scaffold)"]
  - key: budget_for_tools
    question: "What's the infrastructure budget?"
    type: choice
    options: ["free tier only", "up to $50/month", "up to $200/month", "no limit"]
  - key: app_type
    question: "What type of MVP is being built?"
    type: choice
    options: ["SaaS web app", "marketplace", "ecommerce", "internal tool", "API-first product"]

# === EXECUTION METADATA ===
execution:
  required_inputs:
    - name: "Product requirements document or feature list"
      source: "founder/product manager"
      format: "document or structured list"
    - name: "Tech stack decision"
      source: "software/mvp-development/mvp-tech-stack-selection-guide/2026"
      format: "selected stack name"
  outputs:
    - name: "Scaffolded MVP project"
      format: "code repository"
      description: "Complete project with auth, database, API routes, and deployment config — ready for feature development"
    - name: "Deployed staging environment"
      format: "live URL"
      description: "Working application accessible at a staging URL with auth flow functional"
  tools_required:
    - name: "Next.js + Supabase"
      purpose: "Full-stack React framework with PostgreSQL backend"
      tier: "free"
      cost: "$0 (free tiers) to $25/mo (Supabase Pro)"
      alternatives: ["React + Firebase", "Flask + PostgreSQL", "SvelteKit + Supabase"]
    - name: "React + Firebase"
      purpose: "Component-based frontend with NoSQL backend-as-a-service"
      tier: "free"
      cost: "$0 (Spark plan) to $25/mo (Blaze pay-as-you-go)"
      alternatives: ["Next.js + Supabase", "Vue + Firebase"]
    - name: "Flask + PostgreSQL"
      purpose: "Python backend with relational database for API-first MVPs"
      tier: "free"
      cost: "$0 (local dev) to $7/mo (Railway/Render deployment)"
      alternatives: ["FastAPI + PostgreSQL", "Django + PostgreSQL"]
  credentials_needed:
    - service: "Supabase"
      type: "API key (anon + service role)"
      where_to_get: "https://supabase.com/dashboard"
      free_tier_limits: "500 MB database, 1 GB storage, 50K MAU"
    - service: "Firebase"
      type: "Project config (apiKey, authDomain, projectId)"
      where_to_get: "https://console.firebase.google.com"
      free_tier_limits: "1 GiB Firestore, 50K daily reads, 10 GB hosting"
    - service: "Vercel"
      type: "OAuth (GitHub)"
      where_to_get: "https://vercel.com/signup"
      free_tier_limits: "100 GB bandwidth, 100 deployments/day"
  estimated_duration: "30-60 minutes for scaffold + auth + first deploy"
  estimated_cost: "$0 (all free tiers) to $25/mo (Supabase Pro)"

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/software/mvp-development/coded-mvp-architecture-templates/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-03-12)"

# === RELATED UNITS ===
related_kos:
  feeds_into:
    - id: "software/mvp-development/database-schema-design-for-mvps/2026"
      label: "Database schema design after scaffold"
    - id: "software/mvp-development/authentication-authorization-setup/2026"
      label: "Auth configuration and customization"
    - id: "software/mvp-development/payment-integration-setup/2026"
      label: "Payment integration after core app exists"
  related_to:
    - id: "software/landing-pages/landing-page-platform-deployment/2026"
      label: "Deployment patterns for static and hybrid apps"
  alternative_to: []

# === SOURCES ===
sources:
  - id: src1
    title: "Use Supabase with Next.js — Quickstart"
    author: Supabase
    url: https://supabase.com/docs/guides/getting-started/quickstarts/nextjs
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
  - id: src2
    title: "Getting Started: Project Structure — Next.js"
    author: Vercel
    url: https://nextjs.org/docs/app/getting-started/project-structure
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
  - id: src3
    title: "How to Build an MVP with React and Firebase"
    author: SitePoint
    url: https://www.sitepoint.com/react-firebase-build-mvp/
    type: technical_blog
    published: 2024-06-01
    reliability: high
  - id: src4
    title: "Flask App Blueprint — Boilerplate with PostgreSQL"
    author: Jelmer de Jong
    url: https://github.com/jelmerdejong/flask-app-blueprint
    type: open_source
    published: 2024-01-01
    reliability: high
  - id: src5
    title: "MVP Launch Strategy 2025: Next.js, Vercel & Supabase"
    author: ShipAi
    url: https://www.shipai.dev/blog/mvp-launch-strategy-nextjs-vercel-supabase
    type: technical_blog
    published: 2025-03-01
    reliability: high
  - id: src6
    title: "Supabase vs Firebase for Your Startup MVP Backend"
    author: Valtorian
    url: https://www.valtorian.com/blog/supabase-vs-firebase-startup-mvp-backend
    type: technical_blog
    published: 2025-06-01
    reliability: high
  - id: src7
    title: "MVP Development Tools and Tech Stack Every Founder Should Know in 2026"
    author: Cabot Solutions
    url: https://www.cabotsolutions.com/blog/mvp-development-tools-and-tech-stack-every-founder-should-know-in-2026
    type: technical_blog
    published: 2026-01-15
    reliability: high
---

# Coded MVP Architecture Templates

## Purpose

This recipe scaffolds a production-ready MVP codebase using one of three proven architectures — Next.js + Supabase (recommended for web SaaS), React + Firebase (best for real-time/mobile-first), or Flask + PostgreSQL (best for API-first products). The output is a deployed application with authentication, database, API routes, and CI/CD — ready for feature development within 60 minutes. [src1]

## Prerequisites

- [ ] **Product requirements or feature list** — at minimum, a list of core user actions the MVP must support
- [ ] **Tech stack decision** — from [MVP Tech Stack Selection Guide](/software/mvp-development/mvp-tech-stack-selection-guide/2026) or user preference
- [ ] **Node.js 18+** installed (for Next.js/React paths) — [nodejs.org](https://nodejs.org)
- [ ] **Python 3.10+** installed (for Flask path) — [python.org](https://www.python.org/downloads/)
- [ ] **Git** installed and configured with GitHub account
- [ ] **Package manager** — npm 9+ or pnpm 8+ (Node paths), pip + venv (Python path)

## Constraints

- Supabase free tier allows 500 MB database and 50,000 MAU — sufficient for MVP validation but plan upgrade path before launch. [src6]
- Firebase Spark plan limits Firestore to 1 GiB storage and 50,000 daily document reads — exceeding this triggers billing on Blaze plan. [src3]
- Next.js App Router (v14+) defaults to server components — client interactivity requires explicit `"use client"` directives. [src2]
- Flask requires a WSGI server (Gunicorn) for production — never deploy with the built-in development server. [src4]
- All stacks: configure environment variables via `.env.local` (Next.js), `.env` (Flask) — never commit secrets to version control.

## Tool Selection Decision

```
Which stack?
├── Web SaaS with complex queries AND free tier priority
│   └── PATH A: Next.js + Supabase (PostgreSQL, SQL, Row Level Security)
├── Real-time app OR mobile-first AND rapid prototyping priority
│   └── PATH B: React (Vite) + Firebase (Firestore, real-time sync, offline)
├── API-first product OR Python ML/AI integration
│   └── PATH C: Flask + PostgreSQL (REST API, SQLAlchemy ORM, full control)
└── Unsure
    └── DEFAULT: Path A (Next.js + Supabase) — best balance of speed, flexibility, cost
```

| Path | Stack | DB Type | Auth | Deploy | Free Tier Limits | Best For |
|------|-------|---------|------|--------|-----------------|----------|
| A | Next.js 15 + Supabase | PostgreSQL (relational) | Supabase Auth (email, OAuth, magic link) | Vercel | 500 MB DB, 50K MAU | Web SaaS, dashboards, CRUD apps |
| B | React (Vite) + Firebase | Firestore (NoSQL document) | Firebase Auth (email, OAuth, phone) | Firebase Hosting | 1 GiB Firestore, 50K reads/day | Real-time apps, chat, mobile-first |
| C | Flask + PostgreSQL | PostgreSQL (relational) | Flask-Login + Flask-JWT-Extended | Railway / Render | 500 MB DB (Railway), 750 hrs/mo | API-first products, Python ML backends |

## Execution Flow

### Step 1: Scaffold the Project

**Duration**: 5-10 minutes
**Tool**: CLI

**Path A — Next.js + Supabase:**

```bash
# Create Next.js project with Supabase template
npx create-next-app@latest my-mvp -e with-supabase
cd my-mvp

# Install additional dependencies
npm install @supabase/supabase-js @supabase/ssr
npm install -D tailwindcss postcss autoprefixer

# Project structure created:
# app/
#   layout.tsx          # Root layout with Supabase provider
#   page.tsx            # Landing page
#   (auth)/
#     login/page.tsx    # Login form
#     signup/page.tsx   # Signup form
#     callback/route.ts # OAuth callback handler
#   (dashboard)/
#     dashboard/page.tsx # Protected dashboard
# lib/
#   supabase/
#     client.ts         # Browser client
#     server.ts         # Server client
#     middleware.ts      # Auth middleware
# middleware.ts          # Next.js middleware for auth
```

**Path B — React + Firebase:**

```bash
# Create React project with Vite
npm create vite@latest my-mvp -- --template react-ts
cd my-mvp
npm install

# Install Firebase
npm install firebase react-router-dom
npm install -D @types/react-router-dom

# Create folder structure
mkdir -p src/{components,pages,hooks,lib,contexts}

# src/
#   lib/firebase.ts       # Firebase config + initialization
#   contexts/AuthContext.tsx  # Auth provider
#   hooks/useAuth.ts      # Auth hook
#   pages/
#     Login.tsx
#     Dashboard.tsx
#   components/
#     ProtectedRoute.tsx
```

**Path C — Flask + PostgreSQL:**

```bash
# Create project with virtual environment
mkdir my-mvp && cd my-mvp
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# Install dependencies
pip install flask flask-sqlalchemy flask-migrate flask-login
pip install flask-jwt-extended flask-cors python-dotenv
pip install psycopg2-binary gunicorn

# Create project structure
mkdir -p app/{models,routes,templates,static}

# app/
#   __init__.py        # App factory
#   models/
#     user.py          # User model with password hashing
#     __init__.py
#   routes/
#     auth.py          # Login, register, logout
#     api.py           # Core API routes
#     __init__.py
# config.py            # Configuration classes
# run.py               # Entry point
# requirements.txt
```

**Verify**: Run the development server — `npm run dev` (Path A/B) or `flask run` (Path C) — and see the default page at `localhost:3000` or `localhost:5000`.
**If failed**: Check Node.js/Python version (`node -v`, `python --version`). Delete `node_modules` and run `npm install` again. For Flask, ensure venv is activated.

### Step 2: Configure Authentication

**Duration**: 10-15 minutes
**Tool**: Code editor + platform dashboard

**Path A — Supabase Auth:** [src1]

```typescript
// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}

// app/(auth)/login/page.tsx
'use client'
import { createClient } from '@/lib/supabase/client'

export default function Login() {
  const supabase = createClient()

  const handleLogin = async (formData: FormData) => {
    const { error } = await supabase.auth.signInWithPassword({
      email: formData.get('email') as string,
      password: formData.get('password') as string,
    })
    if (!error) window.location.href = '/dashboard'
  }

  const handleOAuth = async (provider: 'google' | 'github') => {
    await supabase.auth.signInWithOAuth({
      provider,
      options: { redirectTo: `${window.location.origin}/auth/callback` }
    })
  }
  // ... render form
}
```

Enable providers in Supabase Dashboard: Authentication > Providers > Enable Email, Google, GitHub.

**Path B — Firebase Auth:** [src3]

```typescript
// src/lib/firebase.ts
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
import { getFirestore } from 'firebase/firestore'

const firebaseConfig = {
  apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
  authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
  projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
  storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
  appId: import.meta.env.VITE_FIREBASE_APP_ID,
}

const app = initializeApp(firebaseConfig)
export const auth = getAuth(app)
export const db = getFirestore(app)
```

Enable providers in Firebase Console: Authentication > Sign-in method > Enable Email/Password, Google.

**Path C — Flask Auth:** [src4]

```python
# app/models/user.py
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from app import db

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(256), nullable=False)
    created_at = db.Column(db.DateTime, default=db.func.now())

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

# app/routes/auth.py
from flask import Blueprint, request, jsonify
from flask_jwt_extended import create_access_token

auth_bp = Blueprint('auth', __name__)

@auth_bp.route('/api/auth/register', methods=['POST'])
def register():
    data = request.get_json()
    if User.query.filter_by(email=data['email']).first():
        return jsonify(error='Email already registered'), 409
    user = User(email=data['email'])
    user.set_password(data['password'])
    db.session.add(user)
    db.session.commit()
    token = create_access_token(identity=user.id)
    return jsonify(access_token=token), 201
```

**Verify**: Create a test account, log in, verify the session persists on page refresh, and log out.
**If failed**: Check environment variables are set correctly in `.env.local` (Next.js) or `.env` (Flask). Verify OAuth redirect URIs match in provider dashboard.

### Step 3: Set Up Database Schema

**Duration**: 5-10 minutes
**Tool**: Supabase Dashboard / Firebase Console / Flask-Migrate

**Path A — Supabase (SQL):** [src1]

```sql
-- Run in Supabase SQL Editor
-- Create a basic table for your core entity
CREATE TABLE IF NOT EXISTS items (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
  title TEXT NOT NULL,
  description TEXT,
  status TEXT DEFAULT 'active' CHECK (status IN ('active', 'archived', 'deleted')),
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);

-- Enable Row Level Security
ALTER TABLE items ENABLE ROW LEVEL SECURITY;

-- Users can only access their own items
CREATE POLICY "Users can view own items" ON items
  FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own items" ON items
  FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own items" ON items
  FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "Users can delete own items" ON items
  FOR DELETE USING (auth.uid() = user_id);
```

**Path B — Firestore (NoSQL):**

```typescript
// Firestore uses schemaless documents — define structure via TypeScript interfaces
interface Item {
  id: string;
  userId: string;
  title: string;
  description?: string;
  status: 'active' | 'archived' | 'deleted';
  createdAt: Timestamp;
  updatedAt: Timestamp;
}

// Security rules (firestore.rules)
// rules_version = '2';
// service cloud.firestore {
//   match /databases/{database}/documents {
//     match /items/{itemId} {
//       allow read, write: if request.auth != null
//         && request.auth.uid == resource.data.userId;
//     }
//   }
// }
```

**Path C — Flask SQLAlchemy:**

```bash
# Initialize migrations
flask db init
flask db migrate -m "Initial schema"
flask db upgrade
```

**Verify**: Insert a test record and query it back. Confirm RLS policies (Supabase) or security rules (Firebase) block unauthorized access.
**If failed**: For Supabase, check RLS is enabled and policies are applied. For Firebase, deploy security rules with `firebase deploy --only firestore:rules`.

### Step 4: Create Core API Routes

**Duration**: 10-15 minutes
**Tool**: Code editor

**Path A — Next.js API Routes (App Router):** [src2]

```typescript
// app/api/items/route.ts
import { createClient } from '@/lib/supabase/server'
import { NextResponse } from 'next/server'

export async function GET() {
  const supabase = await createClient()
  const { data: { user } } = await supabase.auth.getUser()
  if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })

  const { data, error } = await supabase
    .from('items')
    .select('*')
    .order('created_at', { ascending: false })

  if (error) return NextResponse.json({ error: error.message }, { status: 500 })
  return NextResponse.json(data)
}

export async function POST(request: Request) {
  const supabase = await createClient()
  const { data: { user } } = await supabase.auth.getUser()
  if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })

  const body = await request.json()
  const { data, error } = await supabase
    .from('items')
    .insert({ ...body, user_id: user.id })
    .select()
    .single()

  if (error) return NextResponse.json({ error: error.message }, { status: 500 })
  return NextResponse.json(data, { status: 201 })
}
```

**Verify**: Test CRUD operations via browser or curl. Confirm auth middleware rejects unauthenticated requests.
**If failed**: Check Supabase client initialization and environment variables. Verify the server client uses cookies for auth.

### Step 5: Deploy to Staging

**Duration**: 5-10 minutes
**Tool**: CLI + platform dashboard

**Path A — Vercel:** [src5]

```bash
# Push to GitHub first
git init && git add . && git commit -m "Initial MVP scaffold"
gh repo create my-mvp --private --push

# Deploy to Vercel
npx vercel

# Set environment variables in Vercel dashboard:
# NEXT_PUBLIC_SUPABASE_URL
# NEXT_PUBLIC_SUPABASE_ANON_KEY
# SUPABASE_SERVICE_ROLE_KEY (for server-side operations)
```

**Path B — Firebase Hosting:**

```bash
npm install -g firebase-tools
firebase login
firebase init hosting
npm run build
firebase deploy
```

**Path C — Railway:**

```bash
# Install Railway CLI
npm install -g @railway/cli
railway login
railway init
railway up

# Or use Render: connect GitHub repo at render.com
# Set environment variables in the dashboard
```

**Verify**: Visit the staging URL. Test login, create an item, refresh the page, verify data persists.
**If failed**: Check build logs for errors. Verify all environment variables are set in the hosting platform. For Supabase, add the staging domain to Authentication > URL Configuration > Redirect URLs.

### Step 6: Add Error Monitoring and Analytics

**Duration**: 5 minutes
**Tool**: Sentry / Plausible

```bash
# Add Sentry for error monitoring (all paths)
# Path A/B:
npm install @sentry/nextjs  # or @sentry/react
npx @sentry/wizard@latest -i nextjs

# Path C:
pip install sentry-sdk[flask]
```

```python
# Flask Sentry setup
import sentry_sdk
sentry_sdk.init(dsn=os.environ['SENTRY_DSN'], traces_sample_rate=0.1)
```

**Verify**: Trigger a test error and confirm it appears in the Sentry dashboard within 30 seconds.
**If failed**: Verify the Sentry DSN is correct. Check that the SDK is initialized before any route handlers.

## Output Schema

```json
{
  "output_type": "scaffolded_mvp_project",
  "format": "code repository + deployed URL",
  "columns": [
    {"name": "repository_url", "type": "string", "description": "GitHub repository URL with scaffold code", "required": true},
    {"name": "staging_url", "type": "string", "description": "Deployed staging environment URL", "required": true},
    {"name": "stack", "type": "string", "description": "Tech stack used (nextjs-supabase, react-firebase, flask-postgres)", "required": true},
    {"name": "auth_providers", "type": "string", "description": "Enabled authentication methods", "required": true},
    {"name": "database_tables", "type": "string", "description": "Core tables/collections created", "required": true},
    {"name": "api_endpoints", "type": "string", "description": "Available API routes", "required": true}
  ],
  "expected_row_count": "1",
  "sort_order": "N/A",
  "deduplication_key": "repository_url"
}
```

## Quality Benchmarks

| Quality Metric | Minimum Acceptable | Good | Excellent |
|---------------|-------------------|------|-----------|
| Time to first deploy | < 2 hours | < 1 hour | < 30 minutes |
| Auth flow complete (register, login, logout, protected routes) | All 4 working | + OAuth provider | + Magic link + password reset |
| Lighthouse Performance score | > 60 | > 80 | > 90 |
| API response time (p95) | < 2 seconds | < 500ms | < 200ms |
| Security: env vars not in client bundle | Verified | + CSP headers | + Rate limiting + CORS |

**If below minimum**: Check for missing environment variables, unoptimized images, or client-side data fetching that should be server-side. Re-run Lighthouse and fix top 3 recommendations.

## Error Handling

| Error | Likely Cause | Recovery Action |
|-------|-------------|----------------|
| `NEXT_PUBLIC_SUPABASE_URL is not defined` | Missing .env.local file or Vercel env vars | Create `.env.local` with Supabase project URL and anon key from dashboard |
| `Firebase: Error (auth/configuration-not-found)` | Firebase project not initialized or wrong config | Verify Firebase config object matches console values; run `firebase init` |
| `relation "items" does not exist` | Database migration not applied | Run SQL in Supabase SQL Editor or `flask db upgrade` for Flask |
| `ERR_MODULE_NOT_FOUND` | Missing dependency after scaffold | Delete `node_modules`, delete lock file, run `npm install` |
| `500 on API route after deploy` | Environment variables not set in hosting platform | Add all env vars in Vercel/Firebase/Railway dashboard, redeploy |
| `CORS error on API calls` | Missing CORS configuration | Add `Access-Control-Allow-Origin` header; for Flask, configure Flask-CORS |

## Cost Breakdown

| Component | Free Tier | Growth ($25-50/mo) | Scale ($100+/mo) |
|-----------|-----------|---------------------|-------------------|
| Next.js + Supabase | Vercel Hobby: $0, Supabase Free: $0 | Vercel Pro: $20/mo, Supabase Pro: $25/mo | Vercel Team: $20/seat, Supabase Team: $599/mo |
| React + Firebase | Firebase Spark: $0, Vercel: $0 | Firebase Blaze: ~$25-50/mo (usage-based) | Blaze at scale: $100+/mo |
| Flask + PostgreSQL | Railway Hobby: $0 (500 hrs), Render: $0 (750 hrs) | Railway Pro: $5/mo + usage, Render: $7/mo | Railway Team: $20/seat, Render Pro: $25/mo |
| Error monitoring | Sentry: $0 (5K events/mo) | Sentry Team: $26/mo | Sentry Business: $80/mo |
| **Total** | **$0** | **$25-75/mo** | **$150-700+/mo** |

## Anti-Patterns

### Wrong: Starting with a custom authentication system
Building your own auth (password hashing, session management, token rotation, password reset flows) takes 2-4 weeks and introduces security vulnerabilities. Every hour spent on custom auth is an hour not spent validating your core product hypothesis. [src6]

### Correct: Use managed auth from day one
Supabase Auth, Firebase Auth, and Auth0 provide secure, battle-tested authentication in minutes. Migrate to custom auth only if you outgrow the managed service (rare before Series A).

### Wrong: Choosing Firebase for a data-heavy SaaS with complex queries
Firestore requires composite indexes for every query permutation and cannot perform SQL JOINs. A SaaS dashboard with filters, aggregations, and relational data becomes painful on Firestore by month 3. [src6]

### Correct: Match database type to data access patterns
Use PostgreSQL (Supabase) for relational data with complex queries. Use Firestore for real-time sync, offline-first mobile apps, or simple document stores. The database choice is the hardest to change later.

### Wrong: Skipping Row Level Security or Firestore rules
Deploying without RLS (Supabase) or security rules (Firebase) means any authenticated user can access all data. This is a critical security vulnerability, not a shortcut. [src1]

### Correct: Configure access policies before first deploy
Write RLS policies or Firestore rules as part of schema setup (Step 3), not as a post-launch task.

## When This Matters

Use this recipe when a developer needs to go from zero to a deployed, authenticated MVP in under an hour. Requires a tech stack decision already made (or defaults to Next.js + Supabase). This recipe handles scaffolding, auth, database, and deployment — not feature implementation or UI design.

## Related Units

- [MVP Tech Stack Selection Guide](/software/mvp-development/mvp-tech-stack-selection-guide/2026) — choose the right stack before scaffolding
- [Database Schema Design for MVPs](/software/mvp-development/database-schema-design-for-mvps/2026) — design schemas after scaffold
- [Authentication & Authorization Setup](/software/mvp-development/authentication-authorization-setup/2026) — customize auth beyond defaults
- [Payment Integration Setup](/software/mvp-development/payment-integration-setup/2026) — add payments after core app works
- [Landing Page Platform Deployment](/software/landing-pages/landing-page-platform-deployment/2026) — deploy marketing site alongside MVP
