Local Postgres
Local Postgres is the fastest dev loop. No network round-trip, no Neon account, and secrets never leave your machine.
Docker one-liner
Section titled “Docker one-liner”The copy from .env.example:
docker run --name sadie-pg \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=sadie \ -p 5432:5432 -d postgres:16Then in .env.local:
DATABASE_URL=postgres://postgres:postgres@localhost:5432/sadieApply the schema:
pnpm db:migrateThat’s it. pnpm dev should now boot and the first request will bootstrap a user + session.
Native install
Section titled “Native install”If you already run Postgres locally via Homebrew or apt, create a database and user:
createdb sadie# or, in psql:# CREATE DATABASE sadie;Set DATABASE_URL to match your credentials. Anything that is not a .neon.tech or .neon.build hostname is treated as a standard Postgres endpoint and served by the postgres-js driver.
Why driver selection branches on hostname
Section titled “Why driver selection branches on hostname”packages/db/src/client.ts inspects the hostname of DATABASE_URL. Neon hostnames route to the HTTP driver (stateless, edge-friendly). Everything else routes to postgres-js, a pooled TCP driver tuned for long-lived server processes like next dev.
Both drivers expose the same Drizzle query-builder API, so repositories in packages/db/src/repos.ts do not branch on driver.
SADIE_DB_DRIVER override
Section titled “SADIE_DB_DRIVER override”When the hostname is ambiguous (for example, you proxy a Neon database through db.internal), force the driver explicitly:
SADIE_DB_DRIVER=neon-http # force HTTP, regardless of hostnameSADIE_DB_DRIVER=postgres # force pooled TCPThe override is read once on boot. See packages/db/src/client.ts → selectDriver.
Pool sizing
Section titled “Pool sizing”For the postgres-js driver, SADIE_DB_POOL_MAX controls the max pool size (default 5). Raise it for load testing; leave the default for normal dev.
SADIE_DB_POOL_MAX=10SQLite is not supported
Section titled “SQLite is not supported”Sadie’s schema uses Postgres-only features:
pgTable,pgEnum,jsonb,doublePrecisionuniqueIndexwith composite columns$type<T>()branded JSONB columns (compile-time contract)
A SQLite adapter would require a schema rewrite. It is not on the roadmap. If you want zero-infra development, use the Docker one-liner above. It is genuinely one command.
Resetting
Section titled “Resetting”To wipe and re-seed demo fixtures:
pnpm db:resetTo drop the Docker container entirely:
docker rm -f sadie-pg