nestjs

Installation
SKILL.md

NestJS

Commands

Task Command
Generate a module pnpm exec nest generate module <name>
Generate a controller pnpm exec nest generate controller <name>
Generate a service pnpm exec nest generate service <name>
Generate a full resource pnpm exec nest generate resource <name>
Generate a guard pnpm exec nest generate guard <name>
Generate an interceptor pnpm exec nest generate interceptor <name>
Generate a pipe pnpm exec nest generate pipe <name>
Start in dev mode pnpm start:dev
Build pnpm build
Run tests pnpm test

Default action: When adding a new feature, prefer pnpm exec nest generate resource <name> to scaffold the full module, controller, and service in one step — then prune or extend as needed.

Always check package.json scripts before running — script names may vary between auth-server and email-service.

Before generating — explore the project first

Before creating or modifying NestJS code, explore the project to understand:

  • The module tree — read app.module.ts to understand how existing feature modules are registered and which providers (Prisma, config, throttler, etc.) are available globally
  • The existing patterns — look at an existing module's controller, service, and DTO files to match folder structure, naming conventions, and Swagger decoration style
  • How Prisma is injected — confirm whether the DatabaseService is registered as a global provider or must be imported per feature module
  • How authentication is applied — check whether a JwtAuthGuard (or equivalent) is bound globally via APP_GUARD or applied per-controller/route
  • What DTOs look like — check whether class-validator decorators and class-transformer are in use, and how @ApiProperty is applied alongside them

Fastify adapter

Services run on the Fastify HTTP adapter (@nestjs/platform-fastify), not Express. Be aware of these differences:

  • Use FastifyRequest / FastifyReply instead of express.Request / express.Response when typing injected request/response objects
  • Body parsing, file uploads, and multipart forms require Fastify-compatible plugins
  • When manually setting headers or cookies via @Res(), always pass { passthrough: true } to avoid breaking NestJS's response lifecycle

Module structure

  • Keep controllers thin — delegate all business logic to the service layer
  • Keep services focused on a single domain — avoid growing them into god objects by extracting sub-services when needed
  • Place shared types and interfaces in a types/ folder within the module

Swagger documentation

Before writing any Swagger decorators, read nest-cli.json to check whether the @nestjs/swagger CLI plugin is registered under compilerOptions.plugins. This significantly changes what you need to write manually:

  • Plugin active — TypeScript types on DTO properties are automatically introspected and emitted as Swagger schema metadata. @ApiProperty decorators on DTO fields are optional; the plugin infers types, optionality, and class-validator constraints automatically. JSDoc comments on DTO fields are used as the Swagger description. Only add @ApiProperty explicitly when you need to override the inferred value (e.g. a custom example, enum, or description the plugin cannot derive).

  • Plugin not active — every DTO field requires an explicit @ApiProperty (or @ApiPropertyOptional) decorator; nothing is inferred from TypeScript types.

  • Use typed DTO classes as response types — avoid any or raw object shapes so Swagger generates accurate schemas

Security patterns

Maintain the established security conventions on every new endpoint:

  • Authentication — apply @UseGuards(JwtAuthGuard) (or the project's equivalent guard) to all routes requiring an authenticated user; check whether a global APP_GUARD already covers all routes before adding per-route guards
  • Rate limiting — the global ThrottlerModule enforces three windows (1 s / 10 s / 1 min); add @SkipThrottle() only for internal health or status endpoints
  • Helmet — configured globally at the application level; do not override CSP headers at the route level without a security review
  • CORS — configured at the application level with dynamic origin validation; do not add ad-hoc Access-Control-* headers to individual routes

DTOs and validation

Use class-validator and class-transformer for all request body DTOs:

  • ValidationPipe is applied globally — do not manually validate request bodies inside controllers

Workflow notes

  • Run pnpm test before committing to verify service and controller unit tests pass
  • Run pnpm lint after generating new files — ESLint enforces NestJS-specific rules
  • When adding a new database model, update the Prisma schema first — refer to the prisma skill
  • Never instantiate services with new — always inject them through NestJS's DI container
  • Keep AppModule clean — register feature modules rather than importing providers directly into AppModule
Related skills
Installs
10
First Seen
Apr 11, 2026