Does Fastify Work With Drizzle ORM?
Fastify and Drizzle ORM work seamlessly together, offering a modern, type-safe stack for building fast Node.js applications with excellent developer experience.
Quick Facts
How Fastify Works With Drizzle ORM
Fastify and Drizzle ORM are independently designed tools that integrate naturally without friction. Fastify handles HTTP routing and middleware, while Drizzle manages your database queries with full TypeScript support and zero runtime overhead. You instantiate a Drizzle client once and attach it to Fastify's context or as a plugin, making it available across all routes. The real strength is type safety—Drizzle's SQL-like query builder gives you compile-time validation of your database schema, which Fastify's TypeScript support amplifies through route handlers. Neither tool imposes architectural constraints on the other. Fastify's plugin system pairs well with Drizzle's lightweight nature; you can organize database logic in separate plugins or services. Performance is exceptional since both frameworks minimize abstraction overhead. Connection pooling is handled by Drizzle (via the underlying driver), and Fastify's efficient request handling means you get sub-millisecond overhead per request.
Best Use Cases
Quick Setup
npm install fastify drizzle-orm postgres dotenv && npm install -D drizzle-kitimport Fastify from 'fastify';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { users } from './schema';
const client = postgres(process.env.DATABASE_URL!);
const db = drizzle(client);
const app = Fastify();
app.get('/users/:id', async (request, reply) => {
const { id } = request.params as { id: string };
const user = await db.select().from(users).where(eq(users.id, parseInt(id)));
return user;
});
app.post('/users', async (request, reply) => {
const body = request.body as { name: string; email: string };
const result = await db.insert(users).values(body).returning();
reply.code(201);
return result[0];
});
app.listen({ port: 3000 }, (err) => {
if (err) process.exit(1);
console.log('Server running on http://localhost:3000');
});Known Issues & Gotchas
Connection pooling across async context: Drizzle connections must be properly initialized before Fastify starts listening, or requests may fail during startup
Fix: Initialize Drizzle client before calling fastify.listen(), or use Fastify hooks like onReady to establish connections
Transaction handling in concurrent requests: Drizzle transactions are not request-scoped by default, leading to potential isolation issues in high-concurrency scenarios
Fix: Wrap transactions explicitly within route handlers and use proper async/await patterns; consider request-local storage if needed
Schema migrations at startup: Running Drizzle migrations synchronously during Fastify initialization can delay server startup
Fix: Run migrations separately via CLI before deployment, or use Fastify plugins with proper error handling for async migrations
Alternatives
- •Express.js + Prisma: More mature ecosystem but heavier than Fastify; Prisma has better migrations UI
- •Hono + Kysely: Similar lightweight philosophy with SQL query builder; great for edge deployments
- •NestJS + TypeORM: Enterprise-grade framework with built-in ORM; more opinionated structure
Resources
Related Compatibility Guides
Explore more compatibility guides