forRoot
Configure the database connection once in AppModule via DrizzleCrudModule.forRoot.
DrizzleCrudModule.forRoot(config) is called once in your AppModule. It owns the database connection, exposes it globally, and closes it on application shutdown (when the module built it from a connectionString).
Signature
DrizzleCrudModule.forRoot(config: DrizzleCrudConfig): DynamicModuleOptions
| Field | Type | Description |
|---|---|---|
dialect | 'postgresql' | 'mysql' | Required. Database dialect. |
connectionString | string | Connection string. The module builds the connection (PostgreSQL only). |
db | Drizzle instance | Alternatively, pass a Drizzle instance you built yourself (any dialect). |
schema | Record<string, unknown> | Drizzle schema, used when building from connectionString. |
defaults.softDelete | boolean | Enable soft delete for all entities (default true). |
defaults.timestamps | boolean | Auto-manage created_at / updated_at for all entities (default true). |
defaults.pagination | { defaultLimit: number; maxLimit: number } | Pagination defaults (default { 20, 100 }). |
defaults.sortOrder | 'asc' | 'desc' | Opt-in default sort. Entities without an explicit defaultSort fall back to ordering by their created_at column in this direction. Omit to leave findAll unsorted by default. |
sql | { caseSensitive, useReturning, jsonSupport, enableFullTextSearch } | Dialect tuning. useReturning defaults to true for PostgreSQL, false for MySQL. |
Provide exactly one of connectionString or db. The module will throw
if you pass neither, or both.
If your tables have no created_at / updated_at / deleted_at columns,
set defaults: { softDelete: false, timestamps: false } — otherwise
inserts will reference columns that don't exist.
PostgreSQL — let the module build the connection
import { Module } from '@nestjs/common';
import { DrizzleCrudModule } from 'nestjs-drizzle-crud';
import { schema } from './db/schema';
@Module({
imports: [
DrizzleCrudModule.forRoot({
dialect: 'postgresql',
connectionString: process.env.DATABASE_URL,
schema,
defaults: {
softDelete: true,
timestamps: true,
pagination: { defaultLimit: 20, maxLimit: 100 },
},
sql: {
caseSensitive: false,
jsonSupport: true,
enableFullTextSearch: true,
},
}),
],
})
export class AppModule {}The module imports the postgres driver on your behalf and builds a Drizzle instance from your schema. The connection is closed automatically on app shutdown.
Build the connection yourself (any dialect, recommended for MySQL)
If you want full control over the connection — pool size, SSL, advanced mysql2 options, or you're on MySQL — pre-build the Drizzle instance and pass it as db:
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { DrizzleCrudModule } from 'nestjs-drizzle-crud';
import { schema } from './db/schema';
const client = postgres(process.env.DATABASE_URL!);
const db = drizzle(client, { schema });
@Module({
imports: [
DrizzleCrudModule.forRoot({
dialect: 'postgresql',
db,
}),
],
})
export class AppModule {}import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
import { DrizzleCrudModule } from 'nestjs-drizzle-crud';
import { schema } from './db/schema';
const pool = mysql.createPool({
uri: process.env.DATABASE_URL,
connectionLimit: 10,
});
const db = drizzle(pool, { schema });
@Module({
imports: [
DrizzleCrudModule.forRoot({
dialect: 'mysql',
db,
}),
],
})
export class AppModule {}When you pass db, the module does not close the connection on
shutdown — it's your responsibility. This makes it easy to share the same
pool across other Drizzle consumers (custom services, raw queries,
migrations).
sql tuning
| Option | Default | What it does |
|---|---|---|
caseSensitive | false | When false, bare string filter values are compiled to lower(column) = lower(value) (case-insensitive exact match). When true, bare strings use plain equality (collation-dependent). Use the explicit { like } / { ilike } operators for pattern matching. |
useReturning | true (Postgres) / false (MySQL) | Use RETURNING after INSERT to fetch the created row. MySQL doesn't support RETURNING — leave it off. |
jsonSupport | true | Enables JSON column handling in filters and selects. |
enableFullTextSearch | false | Opt-in for fullTextSearch(). Throws if called when false. |
Defaults cheat sheet
defaults: {
softDelete: true, // deletes set deleted_at = now()
timestamps: true, // create/update stamp created_at/updated_at
pagination: { defaultLimit: 20, maxLimit: 100 },
sortOrder: 'desc', // opt-in: created_at fallback for findAll
},
sql: {
caseSensitive: false,
useReturning: dialect === 'postgresql',
jsonSupport: true,
enableFullTextSearch: false,
}When to use forRootAsync
If your config comes from ConfigService (env validation, secrets, dynamic config), use forRootAsync instead of forRoot.