Enforces NestJS best practices for modular architecture, dependency injection scoping, exception filters, class-validator DTO validation, and Drizzle ORM integration. Use when designing modules, providers, filters, DTOs, or ORM in NestJS apps.
How this skill is triggered — by the user, by Claude, or both
Slash command
/developer-kit-typescript:nestjs-best-practicesThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Grounded in the [Official NestJS Documentation](https://docs.nestjs.com/), this skill enforces modular architecture, dependency injection scoping, exception filters, DTO validation with `class-validator`, and Drizzle ORM integration patterns.
assets/templates/controller-template.tsassets/templates/module-template.tsassets/templates/service-template.tsreferences/api-validation-dto.mdreferences/arch-module-boundaries.mdreferences/architecture.mdreferences/db-drizzle-patterns.mdreferences/di-provider-scoping.mdreferences/error-exception-filters.mdGrounded in the Official NestJS Documentation, this skill enforces modular architecture, dependency injection scoping, exception filters, DTO validation with class-validator, and Drizzle ORM integration patterns.
Follow strict module encapsulation. Each domain feature should be its own @Module():
forwardRef() only as a last resort for circular dependencies; prefer restructuringSharedModule for cross-cutting concerns (logging, configuration, caching)See references/arch-module-boundaries.md for enforcement rules.
Choose the correct provider scope based on use case:
| Scope | Lifecycle | Use Case |
|---|---|---|
DEFAULT | Singleton (shared) | Stateless services, repositories |
REQUEST | Per-request instance | Request-scoped data (tenant, user context) |
TRANSIENT | New instance per injection | Stateful utilities, per-consumer caches |
DEFAULT scope — only use REQUEST or TRANSIENT when justifieduseClass, useValue, useFactory, or useExistingSee references/di-provider-scoping.md for enforcement rules.
Understand and respect the NestJS request processing pipeline:
Middleware → Guards → Interceptors (before) → Pipes → Route Handler → Interceptors (after) → Exception Filters
true/false)Standardize error responses across the application:
HttpException for HTTP-specific errorsOrderNotFoundException)ExceptionFilter for consistent error formattingSee references/error-exception-filters.md for enforcement rules.
Enforce input validation at the API boundary:
ValidationPipe globally with transform: true and whitelist: trueclass-validator decoratorsclass-transformer for type coercion (@Type(), @Transform())See references/api-validation-dto.md for enforcement rules.
Integrate Drizzle ORM following NestJS provider conventions:
See references/db-drizzle-patterns.md for enforcement rules.
| Area | Do | Don't |
|---|---|---|
| Modules | One module per domain feature | Dump everything in AppModule |
| DI Scoping | Default to singleton scope | Use REQUEST scope without justification |
| Error Handling | Custom exception filters + domain errors | Bare try/catch with console.log |
| Validation | Global ValidationPipe + DTO decorators | Manual if checks in controllers |
| Database | Repository pattern with injected client | Direct DB queries in controllers |
| Testing | Unit test services, e2e test controllers | Skip tests or test implementation details |
| Configuration | @nestjs/config with typed schemas | Hardcode values or use process.env |
When building a "Product" feature, follow this workflow:
1. Create the module with proper encapsulation:
// product/product.module.ts
@Module({
imports: [DatabaseModule],
controllers: [ProductController],
providers: [ProductService, ProductRepository],
exports: [ProductService], // Only export what others need
})
export class ProductModule {}
2. Create validated DTOs:
// product/dto/create-product.dto.ts
import { IsString, IsNumber, IsPositive, MaxLength } from 'class-validator';
export class CreateProductDto {
@IsString() @MaxLength(255) readonly name: string;
@IsNumber() @IsPositive() readonly price: number;
}
3. Service with error handling:
@Injectable()
export class ProductService {
constructor(private readonly productRepository: ProductRepository) {}
async findById(id: string): Promise<Product> {
const product = await this.productRepository.findById(id);
if (!product) throw new ProductNotFoundException(id);
return product;
}
}
4. Verify module registration:
# Check module is imported in AppModule
grep -r "ProductModule" src/app.module.ts
# Run e2e to confirm exports work
npx jest --testPathPattern="product"
REQUEST-scoped providers cascade to all dependentsforwardRef() — restructure modules to eliminate circular dependenciesValidationPipe — always validate at the API boundary with DTOs@nestjs/config with environment variablesreferences/architecture.md — Deep-dive into NestJS architectural patternsreferences/ — Individual enforcement rules with correct/incorrect examplesassets/templates/ — Starter templates for common NestJS componentsnpx claudepluginhub giuseppe-trisciuoglio/developer-kit --plugin developer-kit-typescriptProvides NestJS patterns and best practices for architecture (modular, clean, CQRS), databases (Prisma, TypeORM, repository), security (JWT, guards), validation, errors, testing, caching, and queues.
Applies opinionated NestJS conventions for backends: modules, dependency injection, controllers/services, DTOs with class-validator, guards/interceptors/pipes, JWT auth, TypeORM/Prisma. Use for REST/GraphQL APIs.
Provides expert guidance on Nest.js architecture, modules, DI, controllers, guards, interceptors, pipes, and testing with Jest/Supertest.