$npx -y skills add Jeffallan/claude-skills --skill nestjs-expertCreates and configures NestJS modules, controllers, services, DTOs, guards, and interceptors for enterprise-grade TypeScript backend applications. Use when building NestJS REST APIs or GraphQL services, implementing dependency injection, scaffolding modular architecture, adding J
| 1 | # NestJS Expert |
| 2 | |
| 3 | Senior NestJS specialist with deep expertise in enterprise-grade, scalable TypeScript backend applications. |
| 4 | |
| 5 | ## Core Workflow |
| 6 | |
| 7 | 1. **Analyze requirements** — Identify modules, endpoints, entities, and relationships |
| 8 | 2. **Design structure** — Plan module organization and inter-module dependencies |
| 9 | 3. **Implement** — Create modules, services, and controllers with proper DI wiring |
| 10 | 4. **Secure** — Add guards, validation pipes, and authentication |
| 11 | 5. **Verify** — Run `npm run lint`, `npm run test`, and confirm DI graph with `nest info` |
| 12 | 6. **Test** — Write unit tests for services and E2E tests for controllers |
| 13 | |
| 14 | ## Reference Guide |
| 15 | |
| 16 | Load detailed guidance based on context: |
| 17 | |
| 18 | | Topic | Reference | Load When | |
| 19 | |-------|-----------|-----------| |
| 20 | | Controllers | `references/controllers-routing.md` | Creating controllers, routing, Swagger docs | |
| 21 | | Services | `references/services-di.md` | Services, dependency injection, providers | |
| 22 | | DTOs | `references/dtos-validation.md` | Validation, class-validator, DTOs | |
| 23 | | Authentication | `references/authentication.md` | JWT, Passport, guards, authorization | |
| 24 | | Testing | `references/testing-patterns.md` | Unit tests, E2E tests, mocking | |
| 25 | | Express Migration | `references/migration-from-express.md` | Migrating from Express.js to NestJS | |
| 26 | |
| 27 | ## Code Examples |
| 28 | |
| 29 | ### Controller with DTO Validation and Swagger |
| 30 | |
| 31 | ```typescript |
| 32 | // create-user.dto.ts |
| 33 | import { IsEmail, IsString, MinLength } from 'class-validator'; |
| 34 | import { ApiProperty } from '@nestjs/swagger'; |
| 35 | |
| 36 | export class CreateUserDto { |
| 37 | @ApiProperty({ example: 'user@example.com' }) |
| 38 | @IsEmail() |
| 39 | email: string; |
| 40 | |
| 41 | @ApiProperty({ example: 'strongPassword123', minLength: 8 }) |
| 42 | @IsString() |
| 43 | @MinLength(8) |
| 44 | password: string; |
| 45 | } |
| 46 | |
| 47 | // users.controller.ts |
| 48 | import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common'; |
| 49 | import { ApiCreatedResponse, ApiTags } from '@nestjs/swagger'; |
| 50 | import { UsersService } from './users.service'; |
| 51 | import { CreateUserDto } from './dto/create-user.dto'; |
| 52 | |
| 53 | @ApiTags('users') |
| 54 | @Controller('users') |
| 55 | export class UsersController { |
| 56 | constructor(private readonly usersService: UsersService) {} |
| 57 | |
| 58 | @Post() |
| 59 | @HttpCode(HttpStatus.CREATED) |
| 60 | @ApiCreatedResponse({ description: 'User created successfully.' }) |
| 61 | create(@Body() createUserDto: CreateUserDto) { |
| 62 | return this.usersService.create(createUserDto); |
| 63 | } |
| 64 | } |
| 65 | ``` |
| 66 | |
| 67 | ### Service with Dependency Injection and Error Handling |
| 68 | |
| 69 | ```typescript |
| 70 | // users.service.ts |
| 71 | import { Injectable, ConflictException, NotFoundException } from '@nestjs/common'; |
| 72 | import { InjectRepository } from '@nestjs/typeorm'; |
| 73 | import { Repository } from 'typeorm'; |
| 74 | import { User } from './entities/user.entity'; |
| 75 | import { CreateUserDto } from './dto/create-user.dto'; |
| 76 | |
| 77 | @Injectable() |
| 78 | export class UsersService { |
| 79 | constructor( |
| 80 | @InjectRepository(User) |
| 81 | private readonly usersRepository: Repository<User>, |
| 82 | ) {} |
| 83 | |
| 84 | async create(createUserDto: CreateUserDto): Promise<User> { |
| 85 | const existing = await this.usersRepository.findOneBy({ email: createUserDto.email }); |
| 86 | if (existing) { |
| 87 | throw new ConflictException('Email already registered'); |
| 88 | } |
| 89 | const user = this.usersRepository.create(createUserDto); |
| 90 | return this.usersRepository.save(user); |
| 91 | } |
| 92 | |
| 93 | async findOne(id: number): Promise<User> { |
| 94 | const user = await this.usersRepository.findOneBy({ id }); |
| 95 | if (!user) { |
| 96 | throw new NotFoundException(`User #${id} not found`); |
| 97 | } |
| 98 | return user; |
| 99 | } |
| 100 | } |
| 101 | ``` |
| 102 | |
| 103 | ### Module Definition |
| 104 | |
| 105 | ```typescript |
| 106 | // users.module.ts |
| 107 | import { Module } from '@nestjs/common'; |
| 108 | import { TypeOrmModule } from '@nestjs/typeorm'; |
| 109 | import { UsersController } from './users.controller'; |
| 110 | import { UsersService } from './users.service'; |
| 111 | import { User } from './entities/user.entity'; |
| 112 | |
| 113 | @Module({ |
| 114 | imports: [TypeOrmModule.forFeature([User])], |
| 115 | controllers: [UsersController], |
| 116 | providers: [UsersService], |
| 117 | exports: [UsersService], // export only when other modules need this service |
| 118 | }) |
| 119 | export class UsersModule {} |
| 120 | ``` |
| 121 | |
| 122 | ### Unit Test for Service |
| 123 | |
| 124 | ```typescript |
| 125 | // users.service.spec.ts |
| 126 | import { Test, TestingModule } |