Quick Start
Clone SaaS Starter, configure modules, run Postgres and Redis, migrate, seed, verify the API and web app, and read troubleshooting — step by step.
Quick Start
This page covers the most common setup paths. For platform-specific installation commands, see Installation. For the complete environment variable reference, see the .env.example file and apps/api/src/config.ts in your repository.
Your first 30-minute win. After running ./setup.sh you will have:
- ✅ A working sign-in page at
/auth/login(use the email and password you set during seeding) - ✅ A full admin dashboard at
/adminwith MRR, users, and feature flags - ✅ A billing/pricing page at
/pricingready to connect to Stripe or Paddle - ✅ An AI chat interface at
/dashboard/ai(configure yourOPENAI_API_KEYto activate) - ✅ API healthcheck at
http://localhost:8000/healthreturning{"status":"ok"}
Then change just 5 env vars and you are production-ready: DATABASE_URL, REDIS_URL, AUTH_SECRET, NEXT_PUBLIC_API_URL, and your billing provider key.
SaaS Starter is a TypeScript monorepo: Next.js (web), Hono (API), workers (BullMQ), Drizzle + PostgreSQL, Redis, and optional Docker. If you skip ahead without Postgres and Redis running, almost everything below will fail — that is normal, not a broken boilerplate.
Support: Contact your purchase channel — email is in your purchase receipt. Include Node + pnpm versions, OS (Windows WSL / macOS / Linux), and whether you use Docker or native Postgres/Redis.
TL;DR
- Install Node 22+, pnpm 10+, PostgreSQL 16+, Redis 7+ (or use Docker for the databases).
git clone→pnpm cli init→./setup.sh(or manual migrate + seed below).- Start the stack (
pnpm devor Docker Compose). - Check
http://localhost:8000/healthand openhttp://localhost:3000. - Sign in with the seeded admin (see First login), then read Configuration and Environment matrix.
What you are installing
| Path | Role |
| --- | --- |
| apps/web/ | Next.js 16 (App Router) — marketing, dashboard, auth UI |
| apps/api/ | Hono on Node — REST, webhooks, Better Auth mount, admin APIs |
| content/docs/ | Documentation content served by the web app at /[locale]/docs |
| packages/db/ | Drizzle schema, migrations, seed scripts |
| packages/auth/ | Better Auth configuration consumed by the API |
| packages/shared/, packages/ai/, … | Plans, AI factory, storage adapters, etc. |
Authoritative folder map and conventions: Project structure.
Prerequisites
| Requirement | Version / notes |
| --- | --- |
| Node.js | 22+ (fnm / nvm) |
| pnpm | 10+ (npm install -g pnpm) |
| PostgreSQL | 16+ (local daemon or Docker volume) |
| Redis | 7+; production uses separate Redis DBs for cache vs queue — see Environment matrix |
| Disk | Plan for ~2 GB under node_modules after install (monorepo). |
| Ports | Defaults below; free them or change your run configuration. |
Default ports
| Service | URL |
| --- | --- |
| Web | http://localhost:3000 |
| API | http://localhost:8000 |
| API health | http://localhost:8000/health (JSON; not under /api/) |
| Docs (when started) | http://localhost:3002 |
Windows (WSL2) and Docker
- Prefer WSL2 with the repo on the Linux filesystem (
~/projects/...), not/mnt/c/..., for native file-watch and symlink performance. - If you use Docker Desktop, ensure WSL integration is enabled for your distro, and that
docker composeworks inside the same environment where you runpnpm.
One-command path (recommended)
Clone the repository
git clone <YOUR_REPO_URL>
cd app
Replace <YOUR_REPO_URL> with your fork, licensed mirror, or tarball instructions from your vendor.
Configure modules (wizard)
pnpm cli init
# alias: pnpm cli init
This updates app.config.ts, .env, writes .nova/wizard-env.snippet.env and .nova/module-prune-checklist.md, and regenerates apps/api/src/generated/active-modules.generated.ts.
If you edit app.config.ts manually later:
pnpm generate:active-modules
pnpm verify:modules
CI runs verify:modules — keep generated output in sync or builds will fail.
Run the setup script
./setup.sh
What it usually does (wording may vary by release):
pnpm installacross the workspace- Copy
.env.example→.envand prompt for required secrets - Migrate and seed the database (development admin + baseline settings)
- Optionally start dev processes (depending on script version)
Start the application (if not already running)
From the repo root:
pnpm dev
This starts the web + API + workers as defined in the root workspace (see root package.json / pnpm-workspace.yaml). If you only need API + web for a smoke test, you can still use full pnpm dev so workers and queues match production-like behavior.
Run the documentation site (optional but recommended)
In a second terminal:
pnpm --filter @app/docs dev
Then open http://localhost:3002 — you are reading this site from that process.
Open and verify
- Web: http://localhost:3000
- API liveness:
curl -sS http://localhost:8000/health— expect JSON with an OK-style payload (exact keys depend on release). - Readiness (when wired):
http://localhost:8000/health/readymay check DB/Redis — useful before load balancers send traffic.
Verify the install (commands)
From the repo root with services running:
curl -sS http://localhost:8000/health
pnpm verify:modules
- If
curlfails with connection refused, the API is not listening on port 8000 — fix process manager / Docker port mapping first. - If
verify:modulesfails, regenerate active modules (see wizard section above).
First login (seeded admin)
The seed script scripts/seed.ts creates a global admin when one does not already exist. Override with environment variables when you run the seed:
| Variable | Description |
| --- | --- |
| ADMIN_EMAIL | Email for the seeded admin account (set via env or wizard) |
| ADMIN_PASSWORD | Password for the seeded admin account (set via env or wizard) |
- Open
/auth/loginon the web app. - Sign in with those credentials.
- Open
/admin(global admin surface). - Change the password before sharing the environment or deploying beyond your machine.
Manual setup (when ./setup.sh is not an option)
pnpm install
cp .env.example .env
# Edit .env — at minimum DATABASE_URL, Redis URLs, AUTH_SECRET
Database:
pnpm --filter "@app/db" run migrate
pnpm --filter "@app/db" run seed
Run dev:
pnpm dev
Docker (all-in-one style):
docker compose up -d postgres redis-cache redis-queue api worker web
Service names, env files, and scaling notes: Docker & scaling. Variable names by surface: Environment matrix.
CLI commands you will reuse
From the repository root (after pnpm install), use pnpm so you run the workspace CLI in packages/cli — not a random global install:
pnpm cli init
pnpm cli add referrals
pnpm cli remove waitlist
pnpm doctor
pnpm cli deploy coolify # see [Deployment](/deploy) for your target
# equivalent:
pnpm exec cli doctor
Do not use npx cli … inside this monorepo. Older npm tried to run the private workspace root as an app and failed with could not determine executable to run; after renaming the root to @app/monorepo, npx cli can instead download a different package name from the public npm registry (not guaranteed to match this repo’s CLI). Always use pnpm cli … or pnpm exec cli … here after pnpm install and building packages/cli (pnpm --filter packages/cli build).
Reading cli doctor output
doctor prints pass/fail lines for environment and connectivity checks (exact list evolves with releases). Use it like this:
- Run
pnpm doctorafter any.envchange. - Fix the first failed check (often
DATABASE_URL, Redis URL, or missing API keys) before chasing UI errors. - Re-run
doctoruntil it is clean, then retrypnpm dev.
If the web UI shows generic errors but /health works, the problem is usually web → API URL (NEXT_PUBLIC_API_URL / cookie / CORS) — see Configuration.
Troubleshooting
ECONNREFUSED to Postgres
- Is Postgres running? (
pg_isready, Docker logs, or Windows Services.) - Does
DATABASE_URLmatch host, port, database, user, password? - After fixing
.env, runpnpm --filter "@app/db" run migrateagain.
Redis connection errors
- Confirm the URL in
.envmatches how Redis is started (password, TLS, DB index). - Cache vs queue may use different Redis logical databases or URLs — Environment matrix.
- In Docker Compose, start redis (and split variants) before api / worker.
Migrations fail
- Do not delete migration files to “fix” a bad state on a real database.
- On a throwaway dev DB, you may drop the database, recreate it, migrate, and seed again.
pnpm verify:modules fails
pnpm generate:active-modules
pnpm verify:modules
Web loads but API errors, 401, or CORS
NEXT_PUBLIC_API_URL(web) must be the browser-reachable API origin (oftenhttp://localhost:8000in dev).- Session cookies and CORS are sensitive to exact origin — see Configuration and the API
configschema inapps/api/src/config.ts(Zod — the source of truth for env names).
What to read next
Support
- Email: Use the contact channel from your purchase receipt
- Help hub: Help & support