home / skills / yldgio / codereview-skills / nestjs

nestjs skill

/skills/nestjs

This skill enforces secure, scalable NestJS practices by applying DTO validation, guards, interceptors, and clean module architecture across features.

npx playbooks add skill yldgio/codereview-skills --skill nestjs

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.5 KB
---
name: nestjs
description: NestJS module architecture, dependency injection, guards, interceptors, and DTO validation
---

## NestJS Code Review Rules

### Security (Critical)
- Validate all DTOs with `ValidationPipe`
- Use `@Exclude()` to hide sensitive fields in responses
- Implement rate limiting with `@nestjs/throttler`
- Sanitize user input before database queries to prevent injection attacks
- Never log sensitive data (passwords, tokens, API keys)
- Use parameterized queries or ORM methods to prevent SQL injection
- Avoid storing sensitive data or security-relevant instructions in HTML comments

### Module Architecture
- One module per feature/domain
- Modules should export only what other modules need
- Use `forRoot`/`forRootAsync` for configurable modules
- Avoid circular dependencies between modules

### Controllers
- Keep controllers thin (delegate to services)
- Use DTOs for request validation, not raw objects
- Apply guards at controller or handler level as appropriate
- Use proper HTTP status codes with `@HttpCode()`
- Follow RESTful conventions for resource naming
- Use consistent routing structure (e.g., `/api/v1/resources`)
- Implement API versioning when needed
- Use descriptive route paths and parameter names

### Services
- Services contain business logic
- Use constructor injection for dependencies
- Services should be stateless (no instance variables for request data)
- Use `@Injectable()` with appropriate scope (default singleton is usually correct)
- Use `async`/`await` for asynchronous operations
- Avoid unhandled promise rejections - always handle errors
- Propagate errors appropriately (don't swallow exceptions)
- Return meaningful error messages from service layer

### DTOs and Validation
- Use `class-validator` decorators on DTO properties
- Apply `ValidationPipe` globally or per-route
- Use `class-transformer` for type transformation
- Create separate DTOs for create/update operations

### Guards and Interceptors
- Guards for authentication/authorization
- Interceptors for logging, transformation, caching
- Use `@UseGuards()` and `@UseInterceptors()` decorators
- Order matters: guards run before interceptors

### Error Handling
- Use built-in exceptions (`NotFoundException`, `BadRequestException`, etc.)
- Create exception filters for custom error formatting
- Don't catch and ignore errors silently

### Configuration (Essential)
- Use `@nestjs/config` for configuration management
- Validate environment variables on startup
- Use `ConfigModule.forRoot()` in app module
- Access config via `ConfigService` dependency injection
- Don't hardcode configuration values in code

### Testing
- Write unit tests using `@nestjs/testing`
- Mock dependencies with `createMock` or manual mocks
- Test controllers, services, and guards separately
- Use `Test.createTestingModule()` for integration tests
- Write e2e tests for critical flows
- Separate test code from implementation code

### File Organization
- Follow consistent file naming (e.g., `user.controller.ts`, `user.service.ts`)
- Group related files in feature folders
- Keep modules, controllers, services, DTOs in separate files
- Use consistent folder structure across features
- Place shared/common code in dedicated folders

### API Documentation (Advanced)
- Use `@nestjs/swagger` for automatic API documentation
- Apply `@Api*` decorators to controllers and DTOs
- Document all endpoints with `@ApiOperation()`
- Define response types with `@ApiResponse()`
- Include examples in `@ApiProperty()` decorators
- Keep Swagger docs up to date with code changes

Overview

This skill codifies practical NestJS code-review rules focused on module architecture, dependency injection, guards, interceptors, and DTO validation. It provides actionable guidance to harden security, organize modules, validate inputs, and keep controllers and services maintainable. The recommendations are concise and oriented toward repeatable best practices for teams building production APIs.

How this skill works

The skill inspects design and implementation patterns: it checks that DTOs are validated and transformed, modules are scoped and avoid circular dependencies, and services remain stateless with proper constructor injection. It highlights where to apply guards and interceptors, enforces safe configuration handling, and recommends security hardening like rate limiting and input sanitization. It also surfaces testing and documentation practices to keep code reliable and discoverable.

When to use it

  • During code reviews for NestJS projects
  • When defining or refactoring module boundaries and exports
  • While implementing authentication, authorization, and request validation
  • Before merging API endpoint changes to ensure consistent routing and status codes
  • When setting up app configuration, environment validation, and secrets management

Best practices

  • Validate all DTOs using ValidationPipe and class-validator decorators
  • Use class-transformer for type conversion and @Exclude() to hide sensitive fields
  • Keep controllers thin: delegate to injectable, stateless services via constructor injection
  • Create one module per domain/feature and export only necessary providers to avoid tight coupling
  • Apply guards for auth/authorization and interceptors for logging, transformation, and caching; remember guards run first
  • Use @nestjs/config with ConfigModule.forRoot() and validate environment variables at startup

Example use cases

  • Enforce request validation by adding DTOs and a global ValidationPipe to prevent malformed input
  • Protect endpoints with guards and implement throttling using @nestjs/throttler for rate limiting
  • Refactor monolithic features into focused modules with clear exports to remove circular dependencies
  • Add class-transformer @Exclude() to response DTOs so tokens and passwords never reach clients
  • Write unit tests for services and guards with @nestjs/testing and e2e tests for critical authentication flows

FAQ

Should ValidationPipe be global or per-route?

Prefer a global ValidationPipe for consistent validation across the app; override per-route only when you need different options.

How do I avoid circular module dependencies?

Design modules around domains, export only public providers, and use forwardRef sparingly. If needed, extract shared providers into a common module to break cycles.