Initial setup
Clone, configure, migrate, seed, run. The reproducible path from a bare checkout to a fully wired SaaS skeleton with audit chain, billing, and demo data.
Initial setup
This guide walks through the full initial setup. The Quickstart shows the four-command happy path. This page is for the moments when the happy path doesn't fit — when you want to know what each step actually does, in what order, and what to do when something complains.
Prerequisites
- Node.js — version
>= 22.20.0(matchespackage.jsonengines). - npm —
>= 10. The boilerplate usespackage-lock.json. Yarn and pnpm are not officially supported. - Git — for cloning. No submodules.
- No Docker required — the local database is PGlite (file-backed), no Postgres install needed.
1. Clone the repository
git clone https://github.com/ixartz/Next-js-Boilerplate.git my-saas
cd my-saasRename the upstream remote so you don't accidentally push back to it :
git remote rename origin upstream
git remote add origin git@github.com:your-org/your-fork.git2. Install dependencies
npm install --legacy-peer-depsThe --legacy-peer-deps flag is mandatory. Storybook 10, Chromatic,
Playwright, and React 19 have peer-dep ranges that npm 10 refuses to
auto-resolve under strict mode. Every CI step in .github/workflows/ uses the
same flag.
3. Create a local environment file
The boilerplate works with no .env.local at all for local dev — every
external provider is optional() in src/libs/Env.ts and degrades to a
no-op. Still, it is useful to copy the template so you have a starting point :
cp .env.example .env.localThe template at .env.example is heavily commented and grouped by surface
(APP, AUTH, DATABASE, STRIPE, EMAIL, STORAGE, OBSERVABILITY, LLM, SECURITY).
Each var is tagged :
# REQUIRED— boot fails or core surface broken without it.# RECOMMENDED— boot succeeds, surface degrades to a no-op.# OPTIONAL— purely additive integration.
For first-run local dev, only one var matters :
# .env.local
AUTH_SECRET=dev_secret_at_least_32_characters_long_xxxxxGenerate a real one with :
openssl rand -base64 32Everything else can stay empty for the first dev session — Stripe, Resend, Sentry, PostHog, Arcjet, S3, Anthropic, OpenAI all have safe fallbacks.
4. Run database migrations + boot the local database
npm run db:setupThis single command does three things :
- Boots a PGlite Postgres on port
5433, file-backed atlocal.db/. - Runs every Drizzle migration in
migrations/in order. - Stays running so the app can connect.
npm run db:setup is idempotent — re-running it on top of an existing
local.db/ only applies new migrations. If the database ever gets into a
weird state, just delete the directory and re-run :
rm -rf local.db
npm run db:setupIf you run a remote Postgres instead (managed RDS, Supabase, Neon), set
DATABASE_URL in .env.local and run the migrations directly :
npm run db:migratedb:migrate reads DATABASE_URL from the env and applies the same migration
set without booting PGlite.
5. Seed demo data
npm run db:seed:demoThe seed script at scripts/seed-demo.ts populates :
- A dev user (
dev@example.com/ any password — sign-in is permissive in dev). - A demo organization with the dev user as
owner. - Sample subscription rows (active
protier). - 50 audit-log rows with mixed kinds (
user.signed_in,credits.consumed,invite.sent, etc.). - A handful of
audit_chainrows so the chain verifier has something to walk. - 25 credits-ledger entries.
- Three system-wide evidence checklists (
chargeback,leakage,compliance). - Two sample webhook endpoints + 10 deliveries (mixed success / failed).
- Five seeded LLM prompts.
The seed is idempotent on dev@example.com — running it twice does not
double-seed. Drop local.db/ if you want a clean slate.
6. Run the dev server
npm run devThe dev server boots on http://localhost:3000 with :
- Next.js 16 App Router + React Compiler.
- Turbopack for dev (HMR).
- Tailwind v4 CSS-first compilation.
- Sentry / PostHog / OpenTelemetry disabled unless their env vars are set.
Open the browser :
/— marketing landing page./sign-in— credentials + OAuth (only the providers with env vars wired)./sign-up?invite=…— invite acceptance flow (auto-accept on sign-up)./dashboard— the operational surface, gated behind sign-in./dashboard/audit-chain— the SHA-256 hash chain viewer (admin only)./dashboard/webhooks— outbound and inbound webhook management.
Sign in as dev@example.com (any password works in dev when no
AUTH_SECRET-bound session exists).
7. Verify the install
Run the standard local checks before you start coding :
npm run lint
npm run check:typesnpm run lint— ESLint over**/*.{ts,tsx,mjs,mts}with the@antfuconfig and the local Next.js plugin.npm run check:types—tsc --noEmit --pretty. Strict mode, no skip.
Both must exit 0 before you commit. The lefthook pre-commit at
lefthook.yml runs them automatically.
For the full QA gate :
npm run test # vitest run — unit + integration
npm run test:e2e # playwright — see playwright.config.ts
npm run check:i18n # translation completeness en + fr
npm run build:next # next build — production bundle checkCommon issues
EADDRINUSE: address already in use :::5433
A previous npm run db:setup is still running. Kill it :
# unix
lsof -i :5433 | awk 'NR>1 {print $2}' | xargs kill -9
# windows powershell
Get-NetTCPConnection -LocalPort 5433 | Select-Object -Expand OwningProcess | ForEach-Object { Stop-Process -Id $_ -Force }ENOENT: no such file or directory, open 'local.db/...'
You ran npm run dev before npm run db:setup. Run them in order, or in
two separate terminals. The dev server expects PGlite to be reachable on
5433.
LlmProviderKeyMissing: ANTHROPIC_API_KEY
You hit a code path that calls Llm.complete() without setting the
provider key. Either set the key in .env.local, or trace the call site
and gate it behind a feature flag.
Email dispatched to stdout (no provider key)
This is expected when RESEND_API_KEY is unset. The email body is
printed to your terminal — copy the rendered HTML block into a browser to
preview. Set RESEND_API_KEY=re_… to dispatch through Resend instead.
What's next
- Authentication — wire OAuth providers and explain the Better Auth migration roadmap.
- Billing & subscriptions — Stripe setup, the three tiers, checkout, customer portal.
- Email layer — Resend, templates, per-category preferences, HMAC unsubscribe links.