drizzle() Options
Drizzle client configuration reference.
drizzle() creates a Drizzle ORM instance using Drizzle Proxy that connects to your superapp backend. Drizzle builds parameterized SQL on the client, and the proxy driver sends SQL + params over HTTP. It returns a standard Drizzle db object with all query methods.
import { drizzle } from '@superapp/db'
import * as schema from './generated/schema'
const db = drizzle({
connection: 'http://localhost:3001',
token: session.token,
schema,
})Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
connection | string | Yes | -- | Your superapp backend URL. The proxy driver sends SQL + params to this endpoint. |
token | string | Yes | -- | A valid JWT obtained from the auth client. Sent as Authorization: Bearer <token> on every request. |
schema | object | Yes | -- | Your generated Drizzle schema object containing table definitions and relations. |
const db = drizzle({
connection: 'https://api.myapp.com',
token: session.token,
schema,
})Schema
The schema is auto-generated from your database by the CLI. It contains standard Drizzle table definitions:
import * as schema from './generated/schema'
// schema.orders → pgTable('orders', { id, amount, status, ... })
// schema.customers → pgTable('customers', { id, name, email, ... })
// schema.ordersRelations → relations(orders, ({ one }) => ({ customer: one(customers, { ... }) }))Generating the Schema
Run the CLI against your running server:
npx @superapp/backend generate --url http://localhost:3001 --output ./generated/schema.tsThis introspects your database via the /schema endpoint and outputs a Drizzle schema file with all table definitions, column types, and relations.
Return Type
drizzle() returns a standard Drizzle database instance:
// Select builder
db.select().from(schema.orders).where(eq(schema.orders.status, 'active'))
db.select({ id: schema.orders.id }).from(schema.orders)
// Mutations
db.insert(schema.orders).values({ amount: 100, status: 'pending' })
db.update(schema.orders).set({ status: 'shipped' }).where(eq(schema.orders.id, 'ord_1'))
db.delete(schema.orders).where(eq(schema.orders.id, 'ord_1'))
// Relational queries
db.query.orders.findMany({ with: { customer: true }, limit: 50 })
db.query.orders.findFirst({ where: eq(schema.orders.id, 'ord_1') })Recommended Setup
Shared Setup File
// lib/db.ts
import { drizzle } from '@superapp/db'
import { createAuth } from '@superapp/auth'
import * as schema from '../generated/schema'
const SUPERAPP_URL = process.env.NEXT_PUBLIC_SUPERAPP_URL!
export const authClient = createAuth(SUPERAPP_URL)
export function createDb(token: string) {
return drizzle({
connection: SUPERAPP_URL,
token,
schema,
})
}React Hook
// hooks/use-db.ts
import { useMemo } from 'react'
import { useSession } from '@superapp/auth'
import { createDb } from '@/lib/db'
export function useDb() {
const { data: session } = useSession()
return useMemo(
() => (session?.token ? createDb(session.token) : null),
[session?.token],
)
}Usage in Components
import { useDb } from '@/hooks/use-db'
import { eq, desc } from 'drizzle-orm'
import * as schema from '@/generated/schema'
export function OrdersList() {
const db = useDb()
async function loadOrders() {
if (!db) return
const orders = await db.select()
.from(schema.orders)
.where(eq(schema.orders.status, 'active'))
.orderBy(desc(schema.orders.createdAt))
.limit(50)
return orders
}
}How It Works
When you call a Drizzle query method, the proxy driver:
- Drizzle builds parameterized SQL on the client (e.g.,
SELECT ... FROM orders WHERE status = $1). - POSTs SQL + params to the backend's
/dataendpoint with the JWT in theAuthorization: Bearerheader. - The server validates the token, applies row-level permissions to the SQL, and executes through DuckDB.
- Returns typed results as JSON, deserialized into the expected TypeScript type.
This is standard Drizzle Proxy — the query syntax is identical to any other Drizzle setup, only the transport layer differs.