Development

Local setup

Clone, install, start infrastructure, migrate the database, seed data, and run the apps.

These steps take you from a fresh clone to a running app with a working sign-in.

Install dependencies

corepack enable
pnpm install

Configure environment

Copy the example file and fill in values. At minimum you need DATABASE_URL and BETTER_AUTH_SECRET; the local defaults in the example already match the Docker services.

cp .env.local.example .env.local

See Environment variables for the full reference.

Start local infrastructure

docker compose up -d

This starts PostgreSQL on :6432 and MinIO on :9000 / :9001.

Apply database migrations

pnpm --filter @repo/database migrate

This runs the ordered Drizzle migrations (drizzle-kit migrate). Use this command, not drizzle-kit push, so local and deployed schemas stay consistent.

Seed an admin + test organization (optional)

pnpm --filter @repo/scripts seed:e2e

The seed is idempotent and additive, so it never truncates data. It creates a platform-admin user, a full-plan organization (E2E Test Fund), and an owner membership linking them. See Signing in for the credentials.

Run the apps

pnpm dev

Turborepo starts every app. For just the product:

pnpm --filter saas dev

The app is then available at http://localhost:3000.

Useful scripts

CommandWhat it does
pnpm devRun all apps in development (Turborepo).
pnpm --filter saas devRun only the product app on :3000.
pnpm --filter docs devRun this documentation site on :3002.
pnpm --filter saas type-checkType-check the product app.
pnpm --filter @repo/database studioOpen Drizzle Studio to browse the database.
pnpm testRun unit tests (Vitest) across the monorepo.
pnpm lint / pnpm formatLint with oxlint / format with oxfmt.

The database scripts (migrate, studio) load their connection string from the repo-root .env file. Make sure DATABASE_URL is set there, not only in .env.local.

On this page