SaaSyBase
SaaSyBase

Getting Started

This guide takes you from zero to a running SaaSyBase instance on your machine. You'll install dependencies, set up your local database, and understand where everything lives so you can start building immediately.

What is SaaSyBase?

SaaSyBase is a complete SaaS foundation — not a starter template. It gives you everything a real SaaS product needs out of the box: authentication, subscription billing with four payment providers, a token/credit system, team and organization support, an admin dashboard, email templates, a blog CMS, support tickets, and more.

You don't rebuild this infrastructure — you build on top of it. Your job is to add your product's unique logic. SaaSyBase handles the business plumbing.

Who is it for?

  • Professional developers who want a battle-tested architecture with clean abstractions, 500+ unit tests, and production-hardened patterns.
  • AI-assisted builders (using Cursor, Lovable, Windsurf, etc.) who want a working SaaS backend they can scaffold their app into without building billing, auth, and admin from scratch.

Prerequisites

You need Node.js ^20.19.0, ^22.12.0, or >=24.0.0 and npminstalled on your machine. That's the full runtime requirement. For the shared repo path, you should also have a PostgreSQL database ready before running Prisma migrations, because the committed migration history now targets PostgreSQL.

Tip

Not sure if Node is installed? Run node --versionin your terminal. If you see a version in one of those supported ranges, you're ready. Node 18 is no longer supported by the current stack. If not, install an updated release from nodejs.org.

Installation

Follow these steps in order to get the app running locally:

0. Choose your local database

The normal repo path is PostgreSQL from day one. If you want the least friction while staying on the same migration lane you'll deploy later, use local PostgreSQL or a hosted PostgreSQL database.

OptionBest forWhat to set
Local PostgreSQLRecommended local setup on the shared migration laneDATABASE_URL="postgresql://..."
Hosted PostgreSQLCloud development, team sharing, and production parityDATABASE_URL="postgresql://..."
SQLiteDisposable local prototyping onlyDATABASE_URL="file:./dev.db"

Useful starting points:

Tip

If you just want the boilerplate running today, do not overthink this. Point DATABASE_URL at any PostgreSQL instance you control and stay on that lane for local, staging, and production migrations.

Typical local PostgreSQL shape:

DATABASE_URL="postgresql://USER:PASSWORD@localhost:5432/DBNAME?schema=public"

Note

If you want PostgreSQL immediately, use the dedicated Local PostgreSQL walkthrough for a copy-paste Docker path and a hosted-provider path.

Warning

SQLite is now a separate disposable local lane. The committed Prisma migration history in this repo is PostgreSQL-only, so do not expect an old SQLite dev.db or SQLite migration chain to deploy cleanly later.

1. Copy the environment template

.env.local
cp .env.example .env.local

This creates your local environment file. The template comes pre-configured with sensible defaults — including AUTH_PROVIDER="nextauth" so you can start without any third-party accounts.

Note

Leave ALLOWED_DEV_ORIGINS empty unless you open the dev server through a custom local hostname or tunnel instead of plain http://localhost:3000. If you do use a custom host, add it as a comma-separated list and restart npm run dev.

2. Install dependencies

npm install

3. Apply existing database migrations

npm run prisma:deploy

This reads env values through prisma.config.ts, so the Prisma CLI picks up your local .env.local automatically. It then creates or updates your local database from DATABASE_URL and applies the existing migration history.

In this repo, that existing migration history is PostgreSQL. DATABASE_URLchooses the target database, but it does not switch Prisma's datasource provider, and Prisma 7 does not support provider = env("DATABASE_PROVIDER").

Use npm run prisma:migrate -- --name your-change later only when you intentionally change prisma/schema.prisma and need to generate a new migration. For a fresh install, npm run prisma:deploy is the correct command.

If Prisma reports a failed old migration on a supposedly fresh setup, inspect the resolved DATABASE_URL first. .env.local, other env files, or an enabled secrets provider like Doppler or Infisical can override it and point Prisma at an older database than the one you intended.

Note

Before the first deploy or whenever a migration behaves unexpectedly, run npm run prisma:diagnose-providerand confirm both the resolved database URL and the schema provider are PostgreSQL.

4. Seed the database

npx prisma db seed

The seed script does more than create the first admin. It also populates the initial catalog and baseline app data, including seeded plans, default settings, and the starter editable site pages the admin UI expects. In an interactive terminal, it prompts you for the admin email and password. For CI or automation, set SEED_ADMIN_PASSWORD and optionally SEED_ADMIN_EMAIL as environment variables to skip the prompt.

Warning

Do not rely on the built-in fallback seed admin credentials outside a disposable local sandbox. If a non-interactive seed run used the default bootstrap admin email/password instead of your own SEED_ADMIN_*values, change those credentials immediately before the app is reachable by anyone else.

The password must satisfy the shared password policy from lib/password-policy.ts: at least 8 characters, with one uppercase letter, one lowercase letter, and one number. The prompt does not ask for password confirmation, so enter it carefully.

To skip admin creation entirely, run npx prisma db seed -- --skip-admin.

Note

npx prisma db seed is the baseline bootstrap seed. Use it to create the starter admin account, plans, settings, and editable site pages the app expects. It is different from npm run demo:seed, which is only for optional local sample data after the main bootstrap is already done.

4b. Optional demo seed for local development

npm run demo:seed

Run this only after npx prisma db seed if you want the shipped admin and user dashboards to feel populated during local development. It adds demo users, organizations, subscriptions, payments, support tickets, notifications, visits, logs, and content so long lists and overview panels are easier to evaluate.

This is not a replacement for the normal Prisma seed and it should not be used as production or staging bootstrap data. Think of it as a local sandbox layer on top of the baseline app setup.

5. Start the dev server

npm run dev

Open http://localhost:3000 to see the landing page. Sign in at /sign-in with the admin credentials you set during seeding, then visit /admin to explore the admin dashboard.

If you run local development on a custom domain such as https://app.localhost.test or through a tunnel URL, keep your URL env vars aligned with that host and set ALLOWED_DEV_ORIGINS so Next.js can serve dev assets to it.

A useful first stop is /admin/system, which gives you a live snapshot of maintenance mode, file storage, bearer-token readiness, webhook configuration, and email transport status.

Note

An environment validation script runs automatically before dev and build. It checks for required variables and logs warnings for missing optional ones — so you'll get clear feedback if anything is misconfigured.

Tip

Keep local development simple: use .env.local on your machine. For staging and production, prefer platform-native encrypted env vars, or use the optional Secrets & Providers bootstrap if your team standardizes on Infisical or Doppler.

Warning

When a secrets provider is enabled, Prisma commands can resolve DATABASE_URL from that provider if the value is not already present locally. Make sure the resolved target is the PostgreSQL database you actually intend to migrate before running npm run prisma:deploy.

Note

If you are still choosing your core stack, the next pages to read are Authentication, Payments, and Deployment.

Core Scripts

These are the commands you'll use most often when working on or operating the project:

CommandWhen to use it
npm run devStart the local development server
npm run dev:turboFaster local startup with Turbopack
npm run buildCreate a production build
npm run startRun the production build locally
npm run typecheckValidate TypeScript before a deploy or PR
npm run lintRun ESLint
npm testRun Vitest unit and integration tests
npm run prisma:studioOpen Prisma Studio to browse the database visually
npm run prisma:migrateCreate and apply a new PostgreSQL Prisma migration when you change the schema
npm run prisma:deployApply the existing PostgreSQL migration history to a fresh or deployed database
npm run prisma:diagnose-providerPrint the resolved database target and schema provider before you migrate
npm run demo:seedAdd optional demo sample data on top of the normal bootstrap seed for local UI exploration
npm run secrets:doctorRun the provider CLI directly and report the detected output shape before boot

Note

npm run dev:turbo uses Turbopack for faster cold starts in development. It does not change the production build path. Use it when you want a faster local loop, and fall back to npm run dev if a plugin or edge case behaves differently.

For vibecoders

Your normal local loop is: npm install → set a PostgreSQL DATABASE_URLnpm run prisma:diagnose-providernpm run prisma:deploynpx prisma db seednpm run dev. Add npm run demo:seedafter the normal seed only when you want demo sample data for local evaluation. You rarely need the other commands unless you're modifying the database schema or preparing a deployment.

Project Structure

Understanding where things live makes it much easier to find your way around — whether you're browsing the code yourself or pointing an AI agent at it.

Top-level directory layout
saasybase/
├── app/                    # Next.js pages and API routes
│   ├── admin/              # Admin dashboard pages
│   ├── api/                # API routes (webhooks, checkout, etc.)
│   ├── dashboard/          # User dashboard pages
│   ├── blog/               # Public blog
│   ├── pricing/            # Public pricing page
│   └── layout.tsx          # Root layout (theme, auth provider)
├── components/             # React components
│   ├── ui/                 # Reusable primitives (Modal, Toast, etc.)
│   ├── admin/              # Admin-specific components
│   ├── dashboard/          # Dashboard-specific components
│   ├── billing/            # Checkout and billing components
│   └── team/               # Team/org management
├── lib/                    # Core business logic
│   ├── auth-provider/      # Auth abstraction (Clerk / NextAuth / Better Auth)
│   ├── payment/            # Payment abstraction (4 providers)
│   ├── email.ts            # Email sending
│   ├── settings.ts         # Admin settings system (50+ keys)
│   └── ...                 # Tokens, teams, coupons, etc.
├── prisma/
│   ├── schema.prisma       # Database schema (25+ models)
│   └── seed.ts             # Database seeding script
├── tests/                  # 500+ Vitest tests across 140+ files
└── .env.example            # Full environment variable template

Route groups and URLs

The project uses Next.js route groups to keep admin and dashboard layouts isolated without changing the browser URL. If you see folders like (valid)in the file tree, that's a route group — it affects layout nesting but doesn't appear in the URL.

The name (valid) is a repo convention, not a special Next.js keyword. It simply groups routes that sit inside the main authenticated app shell. You can rename a route-group folder without changing the public URL, as long as the surrounding imports and layouts still line up.

File pathBrowser URL
app/admin/(valid)/theme/page.tsx/admin/theme
app/dashboard/(valid)/team/page.tsx/dashboard/team
app/admin/(valid)/system/page.tsx/admin/system
app/admin/(valid)/logs/page.tsx/admin/logs
app/docs/api/page.tsx/docs/api

The [...slug] catch-all files under app/admin/ and app/dashboard/ are fallback routes — they handle unmatched paths so the filesystem looks more complex than the actual URL structure.

Where to build your app

Most of your custom product code goes in three places:

  • app/dashboard/ — User-facing pages. Add new pages here for features your users interact with.
  • components/ — React components. Use existing UI primitives from components/ui/ before creating new ones.
  • lib/ — Business logic. Add your domain logic here, using the existing patterns for database access, validation, and error handling.

For AI-assisted builders

The payment, auth, and admin infrastructure is already built. You're extending it, not rebuilding it. Focus on your product idea — the billing, teams, and user management are handled.

Tech Stack

LayerTechnology
FrameworkNext.js 16 (App Router)
AuthClerk, Better Auth, or NextAuth (Auth.js v5) — switchable via AUTH_PROVIDER
PaymentStripe, Paystack, Paddle, Razorpay — switchable via PAYMENT_PROVIDER
DatabasePrisma 7 ORM · committed PostgreSQL migration baseline · SQLite only as a separate disposable local lane
StylingTailwind CSS
Rich Text EditorTipTap (blog posts and editable site pages)
EmailNodemailer (SMTP) or Resend — switchable via EMAIL_PROVIDER
AnalyticsGoogle Analytics 4 (via Data API) + built-in visit tracking
PDF Generationpdf-lib (invoices, refund receipts)
ValidationZod
TestingVitest (unit/integration) + manual regression checks
Monitoring/api/health endpoint

Alternative Dev Scripts

ScriptDescription
npm run devStandard dev server (webpack)
npm run dev:turboDev server with Turbopack (faster cold starts)
npm run dev:fullDev server + Stripe CLI listener in parallel

AI Context Files

The repository ships with several AI-facing context files at the repo root. If you use GitHub Copilot, Cursor, Claude Code, Windsurf, or another coding agent, these files are part of the intended workflow.

FileWhat it does
AGENTS.mdDefines specialized AI agent personas and the areas of the codebase they are expected to understand.
ARCHITECTURE.mdTechnical design of the multi-provider auth and payment layers.
CLAUDE.mdHigh-value coding rules, architecture notes, quick references, and common pitfalls.
CONVENTIONS.mdCoding standards, naming conventions, and file organization rules.
INSTRUCTIONS.mdAdditional repo guidance and conventions for AI-assisted development.
PATTERNS.mdReusable code patterns for API routes, database queries, and state management.
TECH_STACK.mdComprehensive breakdown of the project dependencies and technical choices.

Tip

If you are delegating work to an AI tool, point it at these files early. They explain project-specific rules like auth and payment abstraction, dual-column queries, testing expectations, and the existing admin/dashboard surface area.