Getting Started
nest-extended works two ways: scaffold a brand-new NestJS app with the CLI, or add the packages to an app you already have. Both give you the generic CRUD controller and service, the unified query language, service lifecycle events, soft-delete and auditing.
Option A — Use the CLI
Install the CLI globally:
$npm install -g @nest-extended/cli
Scaffold a new app, then generate your first CRUD resource:
nest-cli g app my-api --db PostgreSQL --orm prisma --validator zod --auth
cd my-api
nest-cli g service catsg service generates the schema/entity, module, service, controller, events class, DTO and
specs — a complete CRUD resource wired into your app. Then start it:
$npm run start
Option B — Add to an existing app
1. Install
Install the shared core and decorators packages plus the adapter for your database
(swap @nest-extended/mongoose for @nest-extended/prisma or @nest-extended/typeorm):
$npm install @nest-extended/core @nest-extended/mongoose @nest-extended/decorators nestjs-cls
2. Register the module
Wire up ClsModule, NestExtendedModule, the global exception filter and the null-response
interceptor in your root module. Import GlobalExceptionFilter from the adapter you installed.
import { Module } from '@nestjs/common';
import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
import { ClsModule } from 'nestjs-cls';
import { NestExtendedModule, NullResponseInterceptor } from '@nest-extended/core';
import { GlobalExceptionFilter } from '@nest-extended/mongoose'; // or /prisma, /typeorm
@Module({
imports: [
ClsModule.forRoot({ global: true, middleware: { mount: true } }),
// forRoot() also discovers @ServiceEvents() classes and registers the controller
// hooks interceptor — see /docs/events.
NestExtendedModule.forRoot({ queryParser: { depth: 20, arrayLimit: 100 } }),
],
providers: [
{ provide: APP_FILTER, useClass: GlobalExceptionFilter },
{ provide: APP_INTERCEPTOR, useClass: NullResponseInterceptor },
],
})
export class AppModule {}3. Create a service and controller
Extend NestService for your model and NestController for the routes — that's the entire
CRUD layer.
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { NestService } from '@nest-extended/mongoose';
import { Cat, CatDocument } from './schemas/cat.schema';
@Injectable()
export class CatsService extends NestService<Cat, CatDocument> {
constructor(@InjectModel(Cat.name) model: Model<CatDocument>) {
super(model);
}
}import { Controller } from '@nestjs/common';
import { NestController } from '@nest-extended/core';
import { CatsService } from './cats.service';
@Controller('cats')
export class CatsController extends NestController<Cat> {
constructor(service: CatsService) {
super(service);
}
}You now have GET /cats, GET /cats/:id, POST /cats, PATCH /cats/:id and
DELETE /cats/:id — with pagination, filtering and soft-delete already wired in.
NestService gives you find, get, create, patch, remove and getCount for free.
Each also has an underscore twin — _find, _get, _create, _patch, _remove — that
does exactly the same work without dispatching lifecycle events; use those
when one service calls another.
Upgrading from 1.0.0
Already running 1.0.0? Bump the packages and run the events codemod:
npm i @nest-extended/core@^1.5.0 @nest-extended/decorators@^1.5.0 @nest-extended/mongoose@^1.5.0
nest-cli m events --dry-runThe migration guide has the full checklist, including the NestJS 12 and Prisma 7 notes.
Next steps
- Querying — the full operator and pagination reference.
- Service Events — run logic around every CRUD operation.
- Soft Delete & Auditing — automatic audit fields.
- CLI Reference — every generator and flag.