Documentation

Freev1.0.0

NextStarter — Production-Ready SaaS Starter (Next.js 16 · Supabase · Stripe)

Installation

npm install
npm run dev

Usage

Prerequisites: Node.js 22.6+ and a Supabase project (free tier is fine). Optional integrations — Google OAuth, Stripe, Resend — can be added later; the app degrades gracefully while their keys are blank.

Configuration. Copy the template and fill in the values:

cp .env.example .env.local
VariablePurpose
DATABASE_URLSupabase transaction pooler (port 6543) — used by the app
DIRECT_URLSupabase session pooler (port 5432) — used by migrations
AUTH_SECRETSigning secret — generate with openssl rand -base64 32
NEXT_PUBLIC_APP_URLYour app's canonical origin (e.g. http://localhost:3000)
NEXT_PUBLIC_SUPABASE_URL / ANON_KEY / SERVICE_ROLE_KEYSupabase API keys (storage)
STRIPE_SECRET_KEY / WEBHOOK_SECRET / price IDsStripe billing
RESEND_API_KEYTransactional email

Database. The schema lives in prisma/schema.prisma (19 models). Create the tables and load the demo dataset:

npm run db:migrate
npm run db:seed

The seed is idempotent and creates demo users, organizations, subscriptions, posts, reports, and feature flags. All seeded accounts use the password Password123!admin@nextstarter.dev (Admin), moderator@nextstarter.dev (Moderator), demo@nextstarter.dev (regular user, org owner).

Extending the template.

  • Add a domain model — declare it in prisma/schema.prisma, run npm run db:migrate, and expose it through server actions + pages following the existing Post pattern (DAL re-checks auth, requireOwnership() guards mutations, writeAuditLog() records admin actions).
  • Change plans/pricing — edit src/lib/plans.ts (single source of truth for the pricing page, plan gating, and Stripe price-ID lookup).
  • Add an email template — drop a default-export .tsx file in src/emails/ and a thin send* wrapper in src/lib/mail.ts; preview with npm run email:dev.
  • Adjust roles/permissions — edit the grant maps in src/lib/permissions.ts.
  • New admin feature — add a page under src/app/admin/, gate it with requireAdmin(), and audit writes via writeAuditLog().
  • Notification types — extend the NotificationType enum (with a migration) and register it in src/lib/notifications-shared.ts.

Testing. The Playwright suite starts its own dev server and isolated, namespaced database seed:

npm run test:e2e

Deployment. Deploy to Vercel (or any Node host), set the same environment variables, run npm run db:deploy against production, and point the Stripe webhook at https://<your-domain>/api/webhooks/stripe.