The release of nest-drizzle-native 0.2.1 introduces a community package designed to make Drizzle ORM feel entirely natural inside NestJS applications.
The core concept is straightforward: preserve Drizzle's explicit, SQL-first philosophy while giving NestJS projects the module, dependency injection, repository, testing, and transaction ergonomics they expect.
The Motivation
Drizzle is excellent because it stays close to SQL and avoids heavy, opaque ORM magic.
NestJS, on the other hand, provides applications with a strong architectural shape built around modules, providers, decorators, testing utilities, lifecycle hooks, and clear dependency boundaries.
A bridge between those two worlds allows teams to build scalable enterprise architectures without turning Drizzle into something it is not. Existing solutions often act as thin connection wrappers, leaving developers to manually solve complex enterprise patterns like cross-service transactions or DTO co-generation.
What it supports today
-
DrizzleModule.forRoot(),forRootAsync(), andforFeature() -
@InjectDrizzle()for direct Drizzle client injection -
@DrizzleRepository()for query-focused provider classes -
@Transactional()/@InjectTransaction()powered natively via@nestjs-cls/transactional - Named connections for multi-database applications
- Testing utilities for clean module and repository testing
- Zero runtime dependencies in the published library package
- Runnable samples covering transactions, DTO validation, optional
drizzle-zodvalidation, Swagger/OpenAPI integration, raw SQL execution, and various driver setups
Let's look at the code
The biggest pain point of using Drizzle in a structured backend is transaction management. Passing a tx object through five layers of injected services completely breaks Dependency Injection.
With nest-drizzle-native, transactions are propagated through the CLS transaction context used by @nestjs-cls/transactional, allowing them to flow seamlessly across your services just by using a decorator:
import { Injectable } from '@nestjs/common';
import { Transactional } from 'nest-drizzle-native';
import { AuditService } from './audit.service';
import { UsersRepository } from './users.repository';
import { CreateUserDto } from './create-user.dto';
@Injectable()
export class UsersService {
constructor(
private readonly usersRepository: UsersRepository,
private readonly auditService: AuditService,
) {}
@Transactional()
async createUser(data: CreateUserDto) {
const user = await this.usersRepository.insert(data);
await this.auditService.logAction('USER_CREATED', user.id);
return user;
}
}
The repository itself is a clean Nest provider that keeps Drizzle's query builder visible instead of hiding SQL behind an Active Record layer:
import { eq } from 'drizzle-orm';
import {
DrizzleRepository,
InjectDrizzle,
} from 'nest-drizzle-native';
import type { AppDatabase } from './database';
import { users } from './schema';
import { CreateUserDto } from './create-user.dto';
@DrizzleRepository()
export class UsersRepository {
constructor(@InjectDrizzle() private readonly db: AppDatabase) {}
async insert(data: CreateUserDto) {
const [user] = await this.db
.insert(users)
.values(data)
.returning();
return user;
}
async findById(id: string) {
const [user] = await this.db
.select()
.from(users)
.where(eq(users.id, id))
.limit(1);
return user;
}
}
What it does not try to do
The goal is strictly avoiding the re-creation of TypeORM or an Active Record layer.
Developers still write real, functional Drizzle queries. The library simply provides those queries with a native NestJS structure through decorators and context management, eliminating the need to pass transaction callbacks (tx) down through multiple layers of services.
Links
- Docs: https://nest-native.github.io/nest-drizzle-native/
- GitHub: https://github.com/nest-native/nest-drizzle-native
- npm: https://www.npmjs.com/package/nest-drizzle-native
- Release: https://github.com/nest-native/nest-drizzle-native/releases/tag/nest-drizzle-native%400.2.1
Community feedback from NestJS and Drizzle users is highly encouraged—especially regarding real-world transaction patterns, testing strategies, multi-database setups, and production adoption. Feel free to open issues or contribute to the repository!
](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filhaomftbws398167mnz.png)
Top comments (0)