# Drizzle
URL: /docs/integrations/drizzle
LLM index: /llms.txt
Description: How the unified schema and runtime fit into Drizzle-based apps.

# Drizzle

Drizzle integration in this repo is now both:

- generation-first when you want generated Drizzle schema files
- runtime-capable when the app already has a Drizzle database instance

## Basic config

```ts
import { defineConfig } from "@farming-labs/orm-cli";
import { authSchema } from "./src/schema";

export default defineConfig({
  schemas: [authSchema],
  targets: {
    drizzle: {
      out: "./generated/drizzle/schema.ts",
      dialect: "pg",
    },
  },
});
```

## Supported Drizzle dialects

- `pg`
- `mysql`
- `sqlite`

## Runtime translation status

The repo now ships a live `@farming-labs/orm-drizzle` runtime package.

That means the unified query API can already run through Drizzle-backed apps for:

- PostgreSQL
- MySQL
- SQLite

The current runtime package unwraps the underlying client from the Drizzle database
handle and routes the unified API through the existing SQL runtime contract. From a
library author point of view, that still means one stable API:

```ts
orm.user.findUnique(...)
orm.user.findMany(...)
orm.user.create(...)
orm.user.update(...)
orm.user.upsert(...)
```

That also means Drizzle inherits the SQL runtime's native relation-loading
path. Reads such as `session.user`, `session.user.profile`, `user.sessions`, and
simple explicit join-table `manyToMany(...)` branches can now load through one
SQL statement. Relation branches still fall back when they add extra
relation-level filtering, ordering, or paging.

That split is about the current Farming ORM planner, not a hard limit in
Drizzle-backed SQL apps. As the SQL runtime grows richer native plans, Drizzle
inherits them automatically.

That live Drizzle matrix now also verifies:

- `integer()` fields with comparison filters
- `json()` fields with raw JSON equality filters
- compound-unique lookups and upserts
- JSON mutation round-trips

## Runtime example

```ts
import { createOrm } from "@farming-labs/orm";
import { createDrizzleDriver } from "@farming-labs/orm-drizzle";
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { authSchema } from "./schema";

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

const db = drizzle(pool);

const orm = createOrm({
  schema: authSchema,
  driver: createDrizzleDriver({
    db,
    dialect: "postgres",
  }),
});

const user = await orm.user.findUnique({
  where: {
    email: "ada@farminglabs.dev",
  },
  select: {
    id: true,
    email: true,
    sessions: {
      select: {
        token: true,
      },
    },
  },
});
```

## Example generated output

From:

```ts
user: model({
  table: "users",
  fields: {
    id: id(),
    email: string().unique().map("email_address"),
    createdAt: datetime().defaultNow(),
  },
});
```

the generator emits output shaped like:

```ts
export const user = pgTable("users", {
  id: text("id").primaryKey(),
  email: text("email_address").notNull().unique(),
  createdAt: timestamp("createdAt").notNull(),
});
```

If you want the generated Drizzle file as a string instead of writing it to
disk, use `renderDrizzleSchema(...)` from `@farming-labs/orm`. The CLI page has
the in-memory example: [CLI generation](/docs/cli#render-as-a-string).

For direct relations, the generator also emits `relations(...)` helpers for:

- `belongsTo(...)`
- `hasOne(...)`
- `hasMany(...)`

Join-table-backed `manyToMany(...)` is still represented through the explicit join
model rather than a direct Drizzle relation shortcut.

## How it fits into a Drizzle app

Typical flow:

1. define the reusable schema once
2. either run `farm-orm generate drizzle` for generated schema files
3. or pass the live Drizzle database to `createDrizzleDriver(...)`
4. keep writing one library-facing query API either way

That means Farming Labs ORM can either feed the app-side Drizzle stack through
generation, or sit above it as a runtime translation layer.

## Why Drizzle teams might like this

- generated table definitions from shared package schemas
- one unified runtime API for shared packages even when the app already uses Drizzle
- no need to manually rewrite the same package tables per app
- easier multi-package monorepo composition

## Important nuance

The Drizzle generator now covers the direct relation helpers above, and the live
runtime already covers:

- `belongsTo(...)`
- `hasOne(...)`
- `hasMany(...)`
- explicit join-table `manyToMany(...)`

Generated Drizzle output still keeps many-to-many relationships explicit through the
join model, which matches how Drizzle teams usually model those tables anyway.

## Local verification

The repo verifies Drizzle locally against PostgreSQL, MySQL, and SQLite.

Run it with:

```bash title="terminal"
pnpm test:local:drizzle
```

## Helpful references

<HoverLink
  href="https://orm.drizzle.team/docs/overview"
  title="Drizzle overview"
  description="Read the official Drizzle overview to understand its SQL-first design, schema style, and how it fits into application code."
  linkLabel="Open Drizzle overview"
>
  Drizzle fundamentals
</HoverLink>
<span>·</span>
<HoverLink
  href="https://orm.drizzle.team/docs/relations"
  title="Drizzle relations"
  description="See how Drizzle models relations explicitly, which maps well to Farming ORM's direct relation helpers and join-table contracts."
  linkLabel="Open Drizzle relation docs"
>
  Drizzle relation docs
</HoverLink>
<span>·</span>
<HoverLink
  href="https://orm.drizzle.team/docs/transactions"
  title="Drizzle transactions"
  description="Review Drizzle's transaction API and compare it to Farming ORM's unified transaction surface for SQL-backed runtimes."
  linkLabel="Open Drizzle transaction docs"
>
  Drizzle transaction docs
</HoverLink>