Skip to content

nest-native/drizzle

Repository files navigation

@nest-native/drizzle

Nest-native Drizzle ORM integration with dependency injection, repositories, and transaction decorators.

NPM Version NPM Downloads Package License Test Coverage Documentation

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/drizzle

Update imports from nest-drizzle-native to @nest-native/drizzle. The old package is frozen at 0.2.1 and no longer maintained.

What This Is

@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:

Why Use It

@nest-native/drizzle keeps Drizzle explicit while giving Nest applications a native integration surface:

  • Module setup via DrizzleModule.forRoot() and DrizzleModule.forRootAsync()
  • Direct client injection through @InjectDrizzle()
  • Repository classes with @DrizzleRepository() and DrizzleModule.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

Compatibility

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.

Repository Layout

This repository contains:

  • packages/drizzle: the @nest-native/drizzle integration package
  • website/docs: Docusaurus documentation for setup, APIs, samples, testing, quality gates, and support
  • sample: focused runnable examples for each supported feature
  • scripts: release, quality, coverage, and report-generation helpers
  • CONTRIBUTING.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.

Installation

npm i @nest-native/drizzle drizzle-orm

Required peers:

npm i @nestjs/common @nestjs/core reflect-metadata rxjs

Install 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/transactional

The 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.

Quick Start

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 {}

Async Configuration

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.

Transactions

@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.

Production Path

  • Generate and apply migrations with standard Drizzle tooling before traffic.
  • Use shutdown to 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.

Testing

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.

Quality Gates

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 ci

Changelog

See CHANGELOG.md for release history and unreleased user-facing changes.

Documentation

The documentation is the canonical source of truth for usage guides and 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.

Philosophy

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.

About

Native Drizzle ORM integration for NestJS — decorators, transactions, repositories, and full NestJS enhancer support.

Resources

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors