SaaS Starter
Getting Started

Installation

Setup local del monorepo en menos de 5 minutos.

Last updated Jul 20, 2026

Prerequisitos

  • Bun 1.3+
  • Node 22+ (sólo para herramientas que aún no soportan Bun)
  • PostgreSQL 15+ (local o Docker)
  • Git

Clone & install

git clone <your-repo> my-saas
cd my-saas
bun install

Variables de entorno

cp apps/server/.env.example apps/server/.env

Edita apps/server/.env:

  • DATABASE_URL — Postgres connection string
  • BETTER_AUTH_SECRET — generá uno con openssl rand -base64 32
  • BETTER_AUTH_URLhttp://localhost:3005 en dev

Database

cd apps/server
bunx prisma migrate dev   # el cliente Prisma ya se genera en `bun install` (postinstall)

Run

# desde la raíz
bun run dev

Dev services (Docker)

The dev stack includes Postgres, Redis, and MailHog (SMTP trap for E2E tests):

docker compose -f docker-compose.dev.yml up -d

MailHog captures all outbound emails. Web UI: http://localhost:8025. To route the server through it, set SMTP_HOST=localhost and SMTP_PORT=1025 in apps/server/.env.

Tests E2E (Playwright)

La suite E2E vive en tests/ (@app/e2e). Corre sobre Node (no Bun) y maneja el stack real. Con Postgres + Redis levantados (docker compose -f docker-compose.dev.yml up -d postgres redis):

bun run e2e          # corre la suite completa contra tu dev stack ya corriendo
bun run e2e:golden   # solo los golden paths (bootstrap, registro, onboarding, billing, dashboard)
bun run e2e:install  # instala el browser Chromium de Playwright (una vez)

bun run e2e:golden es lo que gatea CI en cada PR (job e2e-golden de .github/workflows/ci.yml): levanta server + client por su cuenta y aísla un schema Postgres por corrida. La suite completa corre de noche (.github/workflows/e2e-nightly.yml) contra el stack completo de compose, que además incluye el worker BullMQ y MailHog.

Para espejar el gate localmente antes de pushear:

bash scripts/ci-local.sh --e2e   # lint + typecheck + test + api-freshness + golden E2E

First-run setup

The boilerplate ships with no built-in super-admin. The first time you load any URL with an empty user table, Next.js middleware redirects to /setup and a wizard creates the very first user with platformAdmin = true. After submitting, you land on /admin.

If you ever lose every platform admin (manual UPDATE, an incident wiped the user, etc.), use the recovery CLI to grant platformAdmin = true to an existing user without going through HTTP:

bun run platform:promote -- [email protected]

See Platform admin → Bootstrap for the full flow and the race-safety guarantees.

Troubleshooting

@prisma/client did not initialize — corré bunx prisma generate desde apps/server/.

Server crashea con Invalid environment — el .env no existe o le faltan vars requeridas.

On this page