CapyDB Docs
Getting StartedConnect your framework

Drizzle

Drizzle ORM with node-postgres or postgres.js against CapyDB.

Environment

.env
DATABASE_URL="postgres://user:password@host:6432/db?sslmode=require"
DATABASE_DIRECT_URL="postgres://user:password@host:5432/db?sslmode=require"

Runtime client

src/db.ts
import { drizzle } from 'drizzle-orm/node-postgres'

export const db = drizzle(process.env.DATABASE_URL!)

Or with postgres.js:

import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'

const client = postgres(process.env.DATABASE_URL!, { prepare: false })
export const db = drizzle(client)

prepare: false matters on the pooled URL — transaction pooling does not support postgres.js's named prepared statements.

Migrations

Point drizzle-kit at the direct URL:

drizzle.config.ts
import { defineConfig } from 'drizzle-kit'

export default defineConfig({
  dialect: 'postgresql',
  schema: './src/schema.ts',
  out: './drizzle',
  dbCredentials: {
    url: process.env.DATABASE_DIRECT_URL!,
  },
})
npx drizzle-kit migrate   # or push, against the direct URL

Pitfalls

  • drizzle-kit push/migrate over the pooled URL can hang or fail on DDL; use the direct URL.
  • postgres.js without prepare: false throws prepared statement "..." already exists behind the pooler.
  • Long transactions get cut by the plan's idle-in-transaction timeout (60–120s depending on plan); keep migration batches reasonable.