---
title: Drizzle + Postgres
description: Drizzle ORM with Postgres is the only supported adapter today. Schemas are merged into your project at install time, and you keep ownership of migrations.
section: Integrations
url: /docs/integrations/drizzle
---

# Drizzle + Postgres

Drizzle ORM with Postgres is the only supported adapter today. Schemas are added to your project by the khotan CLI, and you keep ownership of migrations.

## Why Drizzle

- **Schema as TypeScript** — khotan can read, edit, and re-emit your schema safely. No ORM surgery.
- **Migrations you control** — we never run migrations for you. We update files; you run `drizzle-kit`.
- **Postgres-first** — every component is designed for Postgres semantics: row-level locks, `ON CONFLICT`, logical replication, JSONB.

## Project structure

khotan-data expects your Drizzle schema to live at a known path. The CLI detects the schema directory and writes khotan tables there.

```
src/db/
├── index.ts       ← Drizzle client (lazy-init)
├── schema.ts      ← your tables + khotan tables (merged here)
└── migrations/    ← drizzle-kit output

khotan.config.ts   ← khotan-data project config
```

## Standard tables

Running `npx khotan add schema` writes khotan's standard tables into your schema. These are foundational — every component composes on top of them.

- `khotan_plugs` — one row per registered plug.
- `khotan_resources` — one row per logical resource used for cross-system mapping.
- `khotan_flows` — one row per configured flow.
- `khotan_wires` — one row per connected webhook wire.
- `khotan_webhook_handlers` — one row per catch or pass handler.
- `khotan_webhook_events` — one row per captured inbound webhook delivery.
- `khotan_runs` — one row per durable execution.
- `khotan_mappings` — cross-system identity mapping rows for shared resources.

## How schemas are added

The CLI writes khotan's schema file into your Drizzle schema directory, updates the Drizzle config glob if needed, and helps add the barrel re-export.

```ts
// src/lib/khotan/stripe/schema.ts (generated)
import { pgTable, text, timestamp, jsonb } from 'drizzle-orm/pg-core'

export const stripeWebhookEvent = pgTable('stripe_webhook_event', {
  id: text('id').primaryKey(),
  type: text('type').notNull(),
  payload: jsonb('payload').notNull(),
  receivedAt: timestamp('received_at').defaultNow().notNull(),
})
```

```ts
// src/db/schema.ts (patched by khotan)
export * from './tables/users'
export * from '../lib/khotan/stripe/schema'   // ← added by khotan
export * from '../lib/khotan/notion/schema'   // ← added by khotan
```

## Migrations

Use the khotan + Drizzle workflow. khotan prepares the schema files; you still own the migration step.

```terminal
$ npx khotan add schema --yes
$ npx khotan migrate
$ npx khotan migrate --push
```

> **Migration safety:** Always review generated migration SQL before applying to production. khotan updates source files, but you remain the final migration reviewer.

## Postgres requirements

- Postgres 14+ recommended
- Neon, Supabase, Vercel Postgres, RDS, and self-hosted are all supported

### Recommended: Neon

Neon's serverless driver + branching workflow pairs naturally with Vercel deployments and khotan's lazy-init pattern. See the [installation guide](/docs/installation) for setup.

## What about Prisma?

Prisma support is on the roadmap. Today, khotan-data ships Drizzle only — that constraint lets us guarantee correctness of every generated schema patch.
