Drizzle ORM
Drizzle ORM ↗ is a lightweight TypeScript ORM with a focus on type safety. This example demonstrates how to use Drizzle ORM with PostgreSQL via Cloudflare Hyperdrive in a Workers application.
- A Cloudflare account with Workers access
- A PostgreSQL database
- A Hyperdrive configuration to your PostgreSQL database
Install the Drizzle ORM and its dependencies such as the node-postgres ↗ (pg) driver:
npm i drizzle-orm pg dotenvnpm i -D drizzle-kit tsx @types/pg @types/nodeAdd the required Node.js compatibility flags and Hyperdrive binding to your wrangler.jsonc file:
{ // required for database drivers to function "compatibility_flags": [ "nodejs_compat" ], // Set this to today's date "compatibility_date": "2026-02-19", "hyperdrive": [ { "binding": "HYPERDRIVE", "id": "<your-hyperdrive-id-here>" } ]}compatibility_flags = [ "nodejs_compat" ]# Set this to today's datecompatibility_date = "2026-02-19"
[[hyperdrive]]binding = "HYPERDRIVE"id = "<your-hyperdrive-id-here>"With Drizzle ORM, we define the schema in TypeScript rather than writing raw SQL.
-
Create a folder
/db/in/src/. -
Create a
schema.tsfile. -
In
schema.ts, define auserstable as shown below.src/db/schema.ts // src/db/schema.tsimport { pgTable, serial, varchar, timestamp } from "drizzle-orm/pg-core";export const users = pgTable("users", {id: serial("id").primaryKey(),name: varchar("name", { length: 255 }).notNull(),email: varchar("email", { length: 255 }).notNull().unique(),createdAt: timestamp("created_at").defaultNow(),});
Use your Hyperdrive configuration for your database when using the Drizzle ORM.
Populate your index.ts file as shown below.
// src/index.tsimport { Client } from "pg";import { drizzle } from "drizzle-orm/node-postgres";import { users } from "./db/schema";
export interface Env { HYPERDRIVE: Hyperdrive;}
export default { async fetch(request, env, ctx): Promise<Response> { // Create a new client instance for each request. const client = new Client({ connectionString: env.HYPERDRIVE.connectionString, });
// Connect to the database await client.connect();
// Create the Drizzle client with the node-postgres connection const db = drizzle(client);
// Sample query to get all users const allUsers = await db.select().from(users);
return Response.json(allUsers); },} satisfies ExportedHandler<Env>;You can generate and run SQL migrations on your database based on your schema using Drizzle Kit CLI. Refer to Drizzle ORM docs ↗ for additional guidance.
-
Create a
.envfile the root folder of your project, and add your database connection string. The Drizzle Kit CLI will use this connection string to create and apply the migrations..env # .env# Replace with your direct database connection stringDATABASE_URL='postgres://user:password@db-host.cloud/database-name' -
Create a
drizzle.config.tsfile in the root folder of your project to configure Drizzle Kit and add the following content:drizzle.config.ts // drizzle.config.tsimport "dotenv/config";import { defineConfig } from "drizzle-kit";export default defineConfig({out: "./drizzle",schema: "./src/db/schema.ts",dialect: "postgresql",dbCredentials: {url: process.env.DATABASE_URL!,},}); -
Generate the migration file for your database according to your schema files and apply the migrations to your database.
Run the following two commands:
Terminal window npx drizzle-kit generateNo config path provided, using default 'drizzle.config.ts'Reading config file 'drizzle.config.ts'1 tablesusers 4 columns 0 indexes 0 fks[✓] Your SQL migration file ➜ drizzle/0000_mysterious_queen_noir.sql 🚀Terminal window npx drizzle-kit migrateNo config path provided, using default 'drizzle.config.ts'Reading config file 'drizzle.config.ts'Using 'postgres' driver for database querying
Deploy your Worker.
npx wrangler deploy- Learn more about How Hyperdrive Works.
- Refer to the troubleshooting guide to debug common issues.
- Understand more about other storage options available to Cloudflare Workers.