Skip to content

Local Development

Mode 1: Testcontainers (Zero Config)

The easiest way to get started. Requires Docker Desktop.

Install the testcontainers peer dependency:

Terminal window
npm install -D @testcontainers/postgresql

Then use schemaFile:

const proof = await SqlProof.connect({
schemaFile: './schema.sql',
});

SqlProof pulls postgres:16 on first run and caches the container with .withReuse() — subsequent runs start in milliseconds.

Troubleshooting

Cannot connect to the Docker daemon Docker Desktop is not running. Start it from your Applications folder or system tray.

First run takes a long time Docker is pulling the postgres:16 image. This only happens once — subsequent runs reuse the cached container.

Port conflicts Testcontainers assigns a random host port automatically. If you see a port binding error, ensure Docker’s default bridge network isn’t blocked by a VPN or firewall.

RYUK container errors In CI environments with restricted Docker access, set:

TESTCONTAINERS_RYUK_DISABLED=true

Mode 2: Local Postgres

If you have Postgres installed locally, or prefer to manage the container yourself:

Terminal window
# Start a local Postgres container
docker run -d --name pg-test \
-e POSTGRES_PASSWORD=test \
-p 5432:5432 \
postgres:16

Create a .env file in your project root:

DATABASE_URL=postgresql://postgres:test@localhost:5432/postgres

Load it in your tests (e.g. using dotenv):

import 'dotenv/config';
const proof = await SqlProof.connect({
connectionString: process.env.DATABASE_URL!,
schemaFile: './schema.sql', // no Docker needed — uses your local Postgres
});

Or to introspect an existing live schema:

const proof = await SqlProof.connect({
connectionString: process.env.DATABASE_URL!,
schema: 'public',
});

Mode 3: Neon Branching Locally

Neon offers a generous free tier and instant database branches — no local Docker needed.

  1. Sign up at neon.tech (free)
  2. Create a project and note the Project ID
  3. Apply your schema to the default main branch (via Neon SQL editor or psql)
  4. Generate a project-scoped API key: Neon Console → Settings → API Keys

Create a .env file:

NEON_API_KEY=your-api-key-here
NEON_PROJECT_ID=your-project-id-here

In your tests:

import 'dotenv/config';
const proof = await SqlProof.connect({
neon: {
apiKey: process.env.NEON_API_KEY!,
projectId: process.env.NEON_PROJECT_ID!,
parentBranch: 'main', // branch from your schema-ready branch
},
schema: 'public',
});

Each SqlProof.connect() creates a new Neon branch (~1 second). disconnect() deletes it. Free Neon accounts support up to 10 branches simultaneously.


Vitest Configuration

All modes require pool: 'forks':

vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
pool: 'forks',
testTimeout: 120_000,
},
});