RECOMMENDED
Drizzle schema and request/env-scoped clients
Put table definitions in src/db/schema.ts and expose a
factory instead of a global singleton that hard-codes
cloudflare:workers environment access.
import { drizzle } from "drizzle-orm/d1";
import * as schema from "./schema";
export const createDb = (binding: D1Database) =>
drizzle(binding, { schema });
Server functions can call createDb(env.DB) or a small
wrapper around the current cloudflare:workers env.
Durable Objects should use createDb(this.env.DB).
RECOMMENDED
Code-first schema after a database-first baseline
Start database-first by pulling or manually matching the existing D1
schema. After the baseline is reviewed, switch future changes to
code-first Drizzle schema and Drizzle-generated migrations.
import "dotenv/config";
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./src/db/schema.ts",
out: "./drizzle",
dialect: "sqlite",
driver: "d1-http",
dbCredentials: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
token: process.env.CLOUDFLARE_D1_TOKEN!,
},
});
If the team keeps Wrangler as the migration executor, configure
migrations_dir and, for nested Drizzle layouts,
migrations_pattern. Do not have both Wrangler and
Drizzle Kit applying the same new migrations to the same database.