nnestjs-drizzle-crud

Introduction

A complete, type-safe CRUD abstraction for Drizzle ORM in NestJS — configure the connection once, extend one base class per entity, and inherit full CRUD.

What it is

nestjs-drizzle-crud is a thin abstraction over Drizzle ORM that gives every NestJS service a complete, type-safe CRUD surface — find, findOne, findAll, create, update, delete, softDelete, restore, massCreate, massUpdate, massDelete, fullTextSearch, plus filtering, pagination, relations, hooks and transactions — by extending a single generic base class.

It works with both PostgreSQL and MySQL and handles the dialect differences (PostgreSQL's RETURNING vs MySQL's insertId) for you, so your service code is identical across databases.

The two-step mental model

The whole library is built on two steps:

Configure the database connection once

In your AppModule, call DrizzleCrudModule.forRoot(...) with the dialect, connection (either a connection string or a pre-built Drizzle instance), and the schema. The module creates and owns the connection, exposes it globally, and closes it on shutdown.

Per entity: extend the base, bind the table

For each entity, create an empty service class that extends SqlBaseCrudService<Entity>, then register it in a feature module with DrizzleCrudModule.forFeature([{ service, table }]). The service gets every CRUD method automatically, fully typed against your entity.

That's the entire library surface. Everything else — soft delete, bulk ops, full-text search, hooks, transactions, relations — is enabled through configuration, not new APIs to learn.

When to use it

Use nestjs-drizzle-crud when you want:

  • A standard REST/JSON CRUD surface over a relational schema.
  • To stop writing the same findAll / create / update boilerplate in every service.
  • Type-safe query and result types inferred from your Drizzle schema.
  • Soft delete, audit timestamps, and filtering/sorting out of the box.
  • Bulk operations that roll back atomically when one row fails.
  • A library that doesn't hide Drizzle — you can drop down to raw db.select() whenever you need to.

When not to use it

  • Complex aggregate queries. If most of your endpoints are joins, window functions, or domain-specific reads, hand-written Drizzle will be clearer.
  • Has-many / many-to-many relations. Only many-to-one / belongs-to relations are supported. Model those with custom service methods over this.config.db.
  • Non-CRUD write patterns. If your writes are mostly multi-step domain operations (workflows, sagas), use a hand-rolled service and only pull in nestjs-drizzle-crud for the simple entities.
  • GraphQL. The library returns plain objects shaped for REST. Use it with REST controllers; for GraphQL you'll write resolvers against the service methods directly.

Quick taste

import { Module } from '@nestjs/common';
import { DrizzleCrudModule } from 'nestjs-drizzle-crud';
import { schema } from './db/schema';
import { UsersModule } from './users/users.module';

@Module({
  imports: [
    DrizzleCrudModule.forRoot({
      dialect: 'postgresql',
      connectionString: process.env.DATABASE_URL,
      schema,
    }),
    UsersModule,
  ],
})
export class AppModule {}

That's it — your UsersService already exposes find, findOne, findAll, create, update, delete, softDelete, restore, massCreate, massUpdate, count, exists, executeSqlTransaction, and fullTextSearch (Postgres), all typed against User.

Ready to wire it up? Head to the Quick start for a complete 5-minute walkthrough, or read Installation for the full peer-dependency matrix.

On this page