Documentation

Everything you need to know about building with the SaaS Starter Kit

Getting Started

Quick Start
Get your SaaS up and running in minutes

1. Clone and Install

npm install

2. Set Up Environment Variables

Copy .env.example to .env and fill in your credentials:

DATABASE_URL="postgresql://xxxxxx"
DIRECT_URL="postgresql://xxxxxx"

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx
CLERK_SECRET_KEY=sk_test_xxxxx
CLERK_WEBHOOK_SECRET=whsec_xxxxx

STRIPE_SECRET_KEY=sk_test_xxxxx
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx
STRIPE_PRO_PRICE_ID=price_xxxxx

3. Initialize Database

npx prisma generate
npx prisma db push

4. Run Development Server

npm run dev

Open http://localhost:3000 to see your app.

Authentication

Clerk Integration
Secure authentication with minimal setup

Setup

Sign up at clerk.com and get your API keys

Protected Routes

Routes are protected using middleware. All /dashboard routes require authentication.

// middleware.ts export default clerkMiddleware((auth, req) => { if (isProtectedRoute(req)) auth().protect() })

Get Current User

import { getCurrentUser } from '@/lib/clerk-helpers' const user = await getCurrentUser()

Webhooks

User data is automatically synced to your database via Clerk webhooks at /api/webhooks/clerk

Database

Prisma + Supabase
Type-safe database operations

Schema

The database schema includes User, Subscription, and Usage models:

model User { id String @id @default(cuid()) clerkId String @unique email String @unique name String? subscription Subscription? usage Usage[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }

Queries

import { prisma } from '@/lib/prisma' const user = await prisma.user.findUnique({ where: { clerkId: userId }, include: { subscription: true } })

Helper Functions

Use the helper functions in lib/db-helpers.ts for common operations like getting user data, checking subscription status, and tracking usage.

Billing

Stripe Integration
Subscription management made easy

Setup

  1. Create a Stripe account and get your API keys
  2. Create products and prices in Stripe Dashboard
  3. Add price IDs to your environment variables
  4. Configure webhook endpoint at /api/webhooks/stripe

Create Checkout Session

const response = await fetch('/api/stripe/create-checkout-session', { method: 'POST', body: JSON.stringify({ priceId: 'price_xxx' }) })

Customer Portal

Users can manage their subscriptions through the Stripe Customer Portal, accessible from the billing page.

Webhooks

Subscription events are automatically handled via webhooks, updating your database when subscriptions are created, updated, or cancelled.

API Routes

Protected Endpoints
Secure API routes with rate limiting

Available Endpoints

GET /api/userGet current user
PATCH /api/userUpdate user profile
GET /api/usageGet user usage data
POST /api/usageTrack usage event
GET /api/subscriptionGet subscription info
GET /api/analyticsGet analytics data
POST /api/stripe/create-checkout-sessionCreate checkout session
POST /api/stripe/create-portal-sessionCreate customer portal session
POST /api/webhooks/clerkClerk user sync webhook
POST /api/webhooks/stripeStripe subscription webhook

Rate Limiting

API routes include rate limiting to prevent abuse:

import { rateLimit } from '@/lib/rate-limit' const limiter = rateLimit({ interval: 60000, uniqueTokenPerInterval: 500 }) await limiter.check(10, userId)

Client Usage

Use the API client helper for type-safe requests:

import { apiClient } from '@/lib/api-client' const data = await apiClient.get('/api/user')

Webhooks Setup

Clerk Webhook
Sync user data automatically
  1. Go to Clerk Dashboard → Webhooks
  2. Add endpoint: https://your-domain.com/api/webhooks/clerk
  3. Subscribe to: user.created, user.updated, user.deleted
  4. Copy webhook secret to CLERK_WEBHOOK_SECRET
Stripe Webhook
Handle subscription events automatically
  1. Go to Stripe Dashboard → Developers → Webhooks
  2. Add endpoint: https://your-domain.com/api/webhooks/stripe
  3. Subscribe to: checkout.session.completed, invoice.payment_succeeded, customer.subscription.updated, customer.subscription.deleted
  4. Copy webhook secret to STRIPE_WEBHOOK_SECRET

Deployment

Deploy to Vercel
Go live in minutes

Steps

  1. Push your code to GitHub
  2. Import your repository on Vercel
  3. Add environment variables
  4. Deploy

Environment Variables

Make sure to add all required environment variables from .env.example to your Vercel project settings.

Webhooks

Update your webhook URLs in Clerk and Stripe dashboards to point to your production domain.