Does NestJS Work With Drizzle ORM?
NestJS and Drizzle ORM work excellently together, providing a type-safe, lightweight database layer for enterprise Node.js applications.
Quick Facts
How NestJS Works With Drizzle ORM
NestJS and Drizzle ORM integrate seamlessly through NestJS's dependency injection system. You create a provider that manages your Drizzle database instance and inject it into services, following NestJS's modular architecture pattern perfectly. Drizzle's lightweight nature means minimal overhead—no heavy ORM abstractions—while maintaining full TypeScript type safety that NestJS developers expect. The pairing is particularly strong because Drizzle's query builder is SQL-like and composable, aligning well with NestJS's declarative, injectable service pattern. There's no official adapter needed; you simply instantiate Drizzle with your database connection and wrap it in a NestJS provider. This creates a clean separation of concerns: repositories or services handle Drizzle queries, controllers handle HTTP logic, and modules organize dependencies. The developer experience is smooth—you get compile-time SQL validation, autocomplete on schema definitions, and NestJS's powerful testing utilities work naturally with Drizzle instances via mocking or test databases.
Best Use Cases
Quick Setup
npm install drizzle-orm drizzle-kit postgres && npm install -D @types/node// database.provider.ts
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
const client = postgres(process.env.DATABASE_URL);
export const databaseProvider = {
provide: 'DATABASE',
useValue: drizzle(client),
};
// schema.ts
import { pgTable, serial, varchar } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: varchar('name'),
});
// users.service.ts
import { Inject, Injectable } from '@nestjs/common';
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
import { eq } from 'drizzle-orm';
import { users } from './schema';
@Injectable()
export class UsersService {
constructor(@Inject('DATABASE') private db: PostgresJsDatabase) {}
async findById(id: number) {
return this.db.select().from(users).where(eq(users.id, id));
}
}Known Issues & Gotchas
Drizzle transactions don't automatically bind to NestJS request scope
Fix: Manually pass transaction objects through service methods or use AsyncLocalStorage to manage transaction context across the request lifecycle
No built-in repository pattern abstraction like TypeORM provides
Fix: Create custom repository classes or use the Data Mapper pattern by wrapping Drizzle queries in service methods to maintain clean architecture
Migration management requires separate CLI setup; not integrated into NestJS CLI
Fix: Use Drizzle Kit as a standalone migration tool with npm scripts or create custom NestJS commands wrapping drizzle-kit
Alternatives
- •NestJS + TypeORM: More batteries-included with built-in repository pattern and automatic migrations, but heavier and more opinionated
- •NestJS + Prisma: Excellent DX with auto-migrations and a powerful client, but vendor lock-in concerns and slower query generation
- •NestJS + Raw node-postgres: Maximum control and performance, but sacrifices type safety and requires manual query construction
Resources
Related Compatibility Guides
Explore more compatibility guides