Drizzle ORM + PGlite in-memory Postgres: working versions (tested 2026-10-15)
Real Postgres semantics in tests with no server: Drizzle ORM on PGlite (WASM Postgres) with relations, returning() and transactions.
passed2 passed · 0 failed2026-10-15 13:28 UTC- Status
- passed
- Last passed
- 2026-10-15 13:28 UTC
- Tests
- 2 / 2
- Language
- TypeScript
- Runtime
- node v22.23.3
npm install --no-audit --no-fund --ignore-scripts=false npm test
node v22.23.3 linux 6.17.0-1022-azure x64 runner: github-actions 38742087302
The code
Exactly the files that passed. Your agent can pull them with get_recipe("drizzle-pglite-postgres") (install), or see them on GitHub.
{
"name": "drizzle-pglite-postgres",
"private": true,
"type": "module",
"scripts": {
"test": "node --import tsx --test test/*.test.ts"
},
"dependencies": {
"drizzle-orm": "0.45.4",
"@electric-sql/pglite": "0.5.10"
},
"devDependencies": {
"tsx": "4.23.15",
"@types/node": "24.19.2"
}
}
import { PGlite } from "@electric-sql/pglite";
import { drizzle } from "drizzle-orm/pglite";
import { pgTable, serial, text, integer, timestamp } from "drizzle-orm/pg-core";
import { eq, sql } from "drizzle-orm";
export const users = pgTable("users", {
id: serial("id").primaryKey(),
email: text("email").notNull().unique(),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
export const posts = pgTable("posts", {
id: serial("id").primaryKey(),
authorId: integer("author_id").notNull().references(() => users.id),
title: text("title").notNull(),
});
export async function createDb() {
const client = new PGlite(); // in-memory; pass a dir path to persist
const db = drizzle(client);
// In a real app use drizzle-kit migrations; inline DDL keeps the recipe self-contained.
await db.execute(sql`create table users (id serial primary key, email text not null unique, created_at timestamp not null default now())`);
await db.execute(sql`create table posts (id serial primary key, author_id integer not null references users(id), title text not null)`);
return { db, client };
}
export async function createUserWithPost(db: Awaited<ReturnType<typeof createDb>>["db"], email: string, title: string) {
return db.transaction(async (tx) => {
const [u] = await tx.insert(users).values({ email }).returning();
await tx.insert(posts).values({ authorId: u.id, title });
return u;
});
}
export const postsByEmail = (db: Awaited<ReturnType<typeof createDb>>["db"], email: string) =>
db.select({ title: posts.title }).from(posts).innerJoin(users, eq(users.id, posts.authorId)).where(eq(users.email, email));
import { test } from "node:test";
import assert from "node:assert/strict";
import { createDb, createUserWithPost, postsByEmail, users } from "../src/db.ts";
test("insert with returning and join", async () => {
const { db, client } = await createDb();
const u = await createUserWithPost(db, "[email protected]", "Hello");
assert.equal(u.id, 1);
assert.ok(u.createdAt instanceof Date);
assert.deepEqual(await postsByEmail(db, "[email protected]"), [{ title: "Hello" }]);
await client.close();
});
test("unique violation rolls back the transaction", async () => {
const { db, client } = await createDb();
await createUserWithPost(db, "[email protected]", "one");
await assert.rejects(createUserWithPost(db, "[email protected]", "two"));
assert.equal((await db.select().from(users)).length, 1);
await client.close();
});
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.
Related stacks
Drizzle ORM migrations on PGlite (in-memory Postgres)
Apply versioned SQL migrations with Drizzle's PGlite migrator, use Postgres features (jsonb, enums, arrays, onConflictDoUpdate) and test against a fresh in-memory database.
Auth.js Drizzle adapter on PGlite Postgres (database sessions)
Set up @auth/drizzle-adapter with the standard Postgres tables on Drizzle, and test user, account linking and database session lifecycle against in-memory PGlite.
Drizzle ORM + better-sqlite3 CRUD
Typed schema, migrations-free table creation and CRUD with Drizzle on an in-memory SQLite database.
Drizzle ORM + drizzle-zod validated inserts on SQLite
Generate Zod insert and select schemas from Drizzle tables with drizzle-zod, refine them, and validate input before inserting into SQLite.
All Drizzle ORM recipesAll @electric-sql/pglite recipesAll postgres recipes