Skip to main content

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 /admin with MRR, users, and feature flags
  • ✅ A billing/pricing page at /pricing ready to connect to Stripe or Paddle
  • ✅ An AI chat interface at /dashboard/ai (configure your OPENAI_API_KEY to activate)
  • ✅ API healthcheck at http://localhost:8000/health returning {"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

  1. Install Node 22+, pnpm 10+, PostgreSQL 16+, Redis 7+ (or use Docker for the databases).
  2. git clonepnpm cli init./setup.sh (or manual migrate + seed below).
  3. Start the stack (pnpm dev or Docker Compose).
  4. Check http://localhost:8000/health and open http://localhost:3000.
  5. 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 compose works inside the same environment where you run pnpm.

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 install across the workspace
  • Copy .env.example.env and 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

  1. Web: http://localhost:3000
  2. API liveness: curl -sS http://localhost:8000/health — expect JSON with an OK-style payload (exact keys depend on release).
  3. Readiness (when wired): http://localhost:8000/health/ready may 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 curl fails with connection refused, the API is not listening on port 8000 — fix process manager / Docker port mapping first.
  • If verify:modules fails, 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) |

  1. Open /auth/login on the web app.
  2. Sign in with those credentials.
  3. Open /admin (global admin surface).
  4. 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:

  1. Run pnpm doctor after any .env change.
  2. Fix the first failed check (often DATABASE_URL, Redis URL, or missing API keys) before chasing UI errors.
  3. Re-run doctor until it is clean, then retry pnpm 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_URL match host, port, database, user, password?
  • After fixing .env, run pnpm --filter "@app/db" run migrate again.

Redis connection errors

  • Confirm the URL in .env matches 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 (often http://localhost:8000 in dev).
  • Session cookies and CORS are sensitive to exact origin — see Configuration and the API config schema in apps/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