Nest-native Drizzle ORM integration with dependency injection, repositories, and transaction decorators.
Important
Renamed package. This project was previously published as nest-drizzle-native. It is now @nest-native/drizzle (repo: nest-native/drizzle).
npm uninstall nest-drizzle-native
npm install @nest-native/drizzleUpdate imports from nest-drizzle-native to @nest-native/drizzle. The old package is frozen at 0.2.1 and no longer maintained.
@nest-native/drizzle is a community NestJS integration for applications that
want Drizzle ORM with Nest-style modules, dependency injection, repository
classes, lifecycle cleanup, and transaction decorators without hiding Drizzle's
SQL-first query builder.
It solves the Nest/Drizzle shape mismatch without turning Drizzle into Active Record: your app still owns schemas, drivers, migrations, validation, and SQL; the package gives those pieces a clean Nest home.
First paths:
@nest-native/drizzle keeps Drizzle explicit while giving Nest applications a
native integration surface:
- Module setup via
DrizzleModule.forRoot()andDrizzleModule.forRootAsync() - Direct client injection through
@InjectDrizzle() - Repository classes with
@DrizzleRepository()andDrizzleModule.forFeature() - Named connections for multi-database applications
- Shutdown hooks for drivers owned by the Nest module
- Transaction decorator bridges for
@nestjs-cls/transactional - Testing helpers for isolated modules and repository mocks
| Runtime | Supported line |
|---|---|
| Node.js | >=20 |
| NestJS | 11.x |
| Drizzle ORM | >=0.30.0 <2.0.0 |
| Transaction bridge | @nestjs-cls/transactional, optional |
| Drivers | Bring the Drizzle driver your app uses |
For peer dependency policy and API stability, see website/docs/support-policy.md.
This repository contains:
packages/drizzle: the@nest-native/drizzleintegration packagewebsite/docs: Docusaurus documentation for setup, APIs, samples, testing, quality gates, and supportsample: focused runnable examples for each supported featurescripts: release, quality, coverage, and report-generation helpersCONTRIBUTING.md: contributor workflow, including sample/library PR separation
Samples are part of the public learning path. The set includes the full showcase plus focused examples for direct client injection, repositories, async configuration, named connections, transactions, Nest DTO validation, optional Drizzle-Zod validation, driver setup, migrations, health checks, testing, raw SQL, and Swagger.
npm i @nest-native/drizzle drizzle-ormRequired peers:
npm i @nestjs/common @nestjs/core reflect-metadata rxjsInstall the Drizzle driver your app actually uses:
npm i pg
# or mysql2, better-sqlite3, @libsql/client, etc.For @Transactional() and @InjectTransaction(), install and configure the CLS
transaction stack:
npm i @nestjs-cls/transactionalThe published package has no runtime dependencies. Nest, Drizzle, drivers, transactions, Swagger, class-validator, and Drizzle-Zod stay app-owned so teams only install the ecosystems they actually use.
Define schemas with standard Drizzle syntax. The library receives the schema object as-is and does not introduce class entities.
import { Module } from '@nestjs/common';
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import { DrizzleModule } from '@nest-native/drizzle';
import * as schema from './schema';
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
@Module({
imports: [
DrizzleModule.forRoot({
schema,
connection: drizzle(pool, { schema }),
shutdown: () => pool.end(),
}),
],
})
export class AppModule {}Inject the client directly when a service needs the full Drizzle surface.
import { Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nest-native/drizzle';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import * as schema from './schema';
@Injectable()
export class UsersService {
constructor(
@InjectDrizzle()
private readonly db: NodePgDatabase<typeof schema>,
) {}
findMany() {
return this.db.query.users.findMany();
}
}Use repositories as structured homes for query code while keeping Drizzle explicit.
import { Module } from '@nestjs/common';
import {
DrizzleModule,
DrizzleRepository,
InjectDrizzle,
} from '@nest-native/drizzle';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import * as schema from './schema';
@DrizzleRepository()
export class UsersRepository {
constructor(
@InjectDrizzle()
private readonly db: NodePgDatabase<typeof schema>,
) {}
findById(id: string) {
return this.db.query.users.findFirst({
where: (users, { eq }) => eq(users.id, id),
});
}
}
@Module({
imports: [DrizzleModule.forFeature([UsersRepository])],
exports: [UsersRepository],
})
export class UsersModule {}DrizzleModule.forRootAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => {
const pool = new Pool({
connectionString: config.getOrThrow('DATABASE_URL'),
});
return {
schema,
connection: drizzle(pool, { schema }),
shutdown: () => pool.end(),
};
},
});Named connections are supported for multi-database applications.
DrizzleModule.forRoot({
connectionName: 'analytics',
schema: analyticsSchema,
connection: analyticsDb,
});
constructor(@InjectDrizzle('analytics') private readonly analytics: AnalyticsDb) {}Root connections are global by default so feature modules can register
repositories with DrizzleModule.forFeature(). Set isGlobal: false when you
want to keep a connection scoped to one module boundary.
@Transactional() and @InjectTransaction() are bridged to
@nestjs-cls/transactional. This keeps transaction context management on the
well-tested CLS transaction stack instead of introducing a second
AsyncLocalStorage implementation.
import { Injectable } from '@nestjs/common';
import { Transactional } from '@nest-native/drizzle';
@Injectable()
export class BillingService {
@Transactional()
async billCustomer(customerId: string) {
// Calls across injected services can participate in the same transaction
// once @nestjs-cls/transactional is configured for Drizzle.
}
}See website/docs/transactions.md for the required CLS setup.
- Generate and apply migrations with standard Drizzle tooling before traffic.
- Use
shutdownto close driver resources owned by the Nest app. - Keep liveness process-only and readiness backed by a cheap Drizzle check.
- Prefer real Drizzle clients for tests that prove SQL, migrations, transactions, or driver behavior.
Runnable samples cover migrations, health checks, drivers, transactions, testing, validation, raw SQL, and Swagger. Start with the sample catalog when you want a complete working pattern.
import { Test } from '@nestjs/testing';
import {
DrizzleTestModule,
createDrizzleMockClient,
} from '@nest-native/drizzle';
const db = createDrizzleMockClient({
query: {
users: {
findMany: () => [{ id: 'user_1' }],
},
},
});
const module = await Test.createTestingModule({
imports: [DrizzleTestModule.forRoot({ client: db })],
}).compile();Prefer real Drizzle clients for integration tests that prove SQL behavior, transactions, migrations, or driver-specific assumptions. See website/docs/testing.md.
The repository starts with the same review posture as nest-trpc-native while
using node:test and c8 for this package:
- package build, typecheck, and coverage on Node.js 20 and 22
- coverage with
c8, enforced at 100% for statements, branches, functions, and lines - sticky PR comments for coverage, test performance, and cognitive complexity
- cognitive complexity enforcement with SonarJS threshold
15 - package tarball validation
- sample version sync and workspace resolution validation
- dedicated CI sample validation
- supply-chain audit for high-severity issues
Run the local gate with:
npm run ciSee CHANGELOG.md for release history and unreleased user-facing changes.
The documentation is the canonical source of truth for usage guides and support policy:
- Start: Introduction, Why Native, Quick Start, Adoption Guide
- Core API: Repositories, Transactions, API Reference
- Testing: Testing,
- Production: Production Patterns, Multi-Tenant Applications, Deployment, Deployment Recipes, Migration Operations
- Learn by example: Samples
- Project reference: Quality and CI, Contributing, Support Policy, Roadmap
The package stays intentionally small: Nest-native module registration, injection, repositories, transaction bridges, testing helpers, and focused samples without making driver or validation choices mandatory.
See website/docs/roadmap.md for the current roadmap and API boundaries.
This library should feel native in NestJS projects while staying faithful to
Drizzle. Repositories organize query code; they do not replace Drizzle's query
builder, sql template, schema definitions, or type inference.