From harness-claude
Integrates Drizzle ORM with Next.js using Neon/Vercel Postgres, edge runtime, connection pooling, and singleton DB client for hot reload. Covers Server Components, Actions, Routes, and migrations.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Integrate Drizzle with Next.js using Neon/Vercel Postgres, edge runtime, and connection pooling
Sets up Neon and Vercel serverless Postgres for edge/serverless environments like Cloudflare Workers, Vercel Edge, Next.js. Enables HTTP/WebSocket queries, Drizzle/Prisma ORM integration, database branching, migrations, PITR, and fixes connection pool/SSL errors.
Provisions Neon PostgreSQL database and sets up Drizzle ORM with dependencies, credentials, schemas, and migrations for immediate database connectivity and querying.
Provides expertise in Drizzle ORM for TypeScript: schema design, relational queries, Drizzle Kit migrations, and serverless integrations with Neon, Supabase, PlanetScale.
Share bugs, ideas, or general feedback.
Integrate Drizzle with Next.js using Neon/Vercel Postgres, edge runtime, and connection pooling
# Neon (serverless PostgreSQL)
npm install drizzle-orm @neondatabase/serverless
npm install -D drizzle-kit
# Vercel Postgres
npm install drizzle-orm @vercel/postgres
npm install -D drizzle-kit
# node-postgres (standard)
npm install drizzle-orm pg
npm install -D drizzle-kit @types/pg
// src/db/index.ts
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';
import * as schema from './schema';
const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql, { schema });
For development with hot module reload, use a global singleton:
// src/db/index.ts
import { drizzle, NeonHttpDatabase } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';
import * as schema from './schema';
const globalForDb = globalThis as unknown as {
db: NeonHttpDatabase<typeof schema>;
};
if (!globalForDb.db) {
const sql = neon(process.env.DATABASE_URL!);
globalForDb.db = drizzle(sql, { schema });
}
export const db = globalForDb.db;
// app/users/page.tsx
import { db } from '@/db';
import { users } from '@/db/schema';
export default async function UsersPage() {
const allUsers = await db.query.users.findMany({
orderBy: (users, { desc }) => [desc(users.createdAt)],
});
return <UserList users={allUsers} />;
}
// app/users/actions.ts
'use server';
import { db } from '@/db';
import { users } from '@/db/schema';
import { eq } from 'drizzle-orm';
import { revalidatePath } from 'next/cache';
export async function updateUserName(userId: string, name: string) {
await db.update(users).set({ name }).where(eq(users.id, userId));
revalidatePath('/users');
}
// app/api/users/route.ts
import { db } from '@/db';
import { users } from '@/db/schema';
import { NextResponse } from 'next/server';
export async function GET() {
const allUsers = await db.query.users.findMany();
return NextResponse.json(allUsers);
}
// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
{
"scripts": {
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate",
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio"
}
}
// For edge runtime (middleware, edge API routes)
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';
// For Node.js runtime (standard API routes, Server Components)
import { drizzle } from 'drizzle-orm/neon-serverless';
import { Pool, neonConfig } from '@neondatabase/serverless';
Next.js serverless functions create a new runtime per invocation. Without connection pooling, each invocation opens (and may not close) a database connection, exhausting the connection limit.
Driver selection:
neon-http — uses HTTP protocol, works in Edge Runtime, one query per request (no transactions), lowest latency for single queriesneon-serverless — uses WebSocket protocol, supports transactions, works in both Edge and Node.js runtimesnode-postgres — standard PostgreSQL driver, Node.js only, supports everything, requires connection pooling for serverlessConnection pooling strategies:
?pooling=true to the connection string. Uses PgBouncer on Neon's infrastructure@vercel/postgresDIRECT_URL for migrations and a pooled DATABASE_URL for runtime queriesEnvironment variables pattern:
# Pooled connection for runtime queries
DATABASE_URL="postgresql://user:pass@host/db?sslmode=require"
# Direct connection for migrations (bypasses pooler)
DIRECT_URL="postgresql://user:pass@direct-host/db?sslmode=require"
Trade-offs:
neon-http is the fastest single-query driver but cannot run transactions — use neon-serverless if you need multi-statement transactionsfs access — run migrations via CLI or in a Node.js environment, not at edge request timehttps://orm.drizzle.team/docs/get-started-postgresql