# NestJS Administrator & Developer Guide

## 1. Architecture Overview

NestJS is a TypeScript-first framework for building server-side Node.js applications. It provides a modular, decorator-driven architecture inspired by Angular, centered around dependency injection, a request processing pipeline, and platform-agnostic HTTP layer abstractions. The framework is published as a monorepo of packages under the `@nestjs` scope, each addressing a specific concern — from HTTP handling to microservices, WebSockets, and testing.

The core design philosophy separates the framework into three layers: the **platform layer** (HTTP adapters for Express or Fastify), the **core layer** (DI container, lifecycle management, routing, middleware pipeline), and the **common layer** (decorators, interfaces, pipes, exceptions, and utilities shared across all parts of the framework).

### Architecture Diagram

```text
                    ┌─────────────────────────────────────────┐
                    │              NestFactory                 │
                    │  create() / createMicroservice()         │
                    └─────────────┬───────────────────────────┘
                                  │
                    ┌─────────────▼───────────────────────────┐
                    │         NestApplication                  │
                    │  ┌──────────────────────────────────┐   │
                    │  │      ApplicationConfig            │   │
                    │  │  (global prefix, versioning,      │   │
                    │  │   pipes, guards, interceptors,    │   │
                    │  │   filters, WebSocket adapter)     │   │
                    │  └──────────────────────────────────┘   │
                    │  ┌──────────────────────────────────┐   │
                    │  │       NestContainer               │   │
                    │  │  ┌────────┐  ┌────────┐          │   │
                    │  │  │Module A│  │Module B│  ...      │   │
                    │  │  │ provs  │  │ provs  │          │   │
                    │  │  │ ctrls  │  │ ctrls  │          │   │
                    │  │  └────────┘  └────────┘          │   │
                    │  └──────────────────────────────────┘   │
                    │  ┌──────────────────────────────────┐   │
                    │  │    Request Pipeline               │   │
                    │  │  Middleware → Guards → Intercept  │   │
                    │  │  → Pipes → Handler → Intercept   │   │
                    │  │  → Exception Filters              │   │
                    │  └──────────────────────────────────┘   │
                    └─────────────┬───────────────────────────┘
                                  │
                    ┌─────────────▼───────────────────────────┐
                    │      Platform Adapter (HTTP)             │
                    │  ExpressAdapter  │  FastifyAdapter        │
                    └──────────────────────────────────────────┘
```

### Component Inventory

| Component | Package | Role |
|---|---|---|
| `NestFactory` | `@nestjs/core` | Bootstrap entry point; creates application instances |
| `NestApplication` | `@nestjs/core` | HTTP application with routing, middleware, lifecycle |
| `NestApplicationContext` | `@nestjs/core` | Standalone context (no HTTP) for workers, scripts, REPL |
| `NestContainer` | `@nestjs/core` | DI container holding all module instances and providers |
| `Injector` | `@nestjs/core` | Resolves and instantiates providers within the container |
| `RoutesResolver` | `@nestjs/core` | Maps controller decorators to HTTP routes |
| `MiddlewareModule` | `@nestjs/core` | Registers and executes middleware chains |
| `ApplicationConfig` | `@nestjs/core` | Global configuration state (prefix, pipes, guards, etc.) |
| `MetadataScanner` | `@nestjs/core` | Scans class prototypes for decorated methods |
| `DiscoveryService` | `@nestjs/core` | Programmatic access to all registered providers/controllers |
| `Reflector` | `@nestjs/core` | Read metadata set by decorators on classes/methods |
| `LazyModuleLoader` | `@nestjs/core` | Load modules on demand at runtime |
| `SerializedGraph` / `GraphInspector` | `@nestjs/core` | Inspect the dependency graph for debugging |
| `ExpressAdapter` | `@nestjs/platform-express` | Wraps Express for NestJS |
| `FastifyAdapter` | `@nestjs/platform-fastify` | Wraps Fastify for NestJS |
| `IoAdapter` | `@nestjs/platform-socket.io` | Socket.IO WebSocket adapter |
| `WsAdapter` | `@nestjs/platform-ws` | `ws` library WebSocket adapter |
| `ClientsModule` | `@nestjs/microservices` | Registers microservice client proxies |
| `Server` (abstract) | `@nestjs/microservices` | Base class for all transport servers |
| `ClientProxy` (abstract) | `@nestjs/microservices` | Base class for all transport clients |
| `Test` | `@nestjs/testing` | Creates testing module instances |

### Technology Stack

| Technology | Role | Version |
|---|---|---|
| TypeScript | Primary language | 5.x |
| Node.js | Runtime | >= 20 |
| Express | Default HTTP adapter | 5.x |
| Fastify | Alternative HTTP adapter | 5.x |
| RxJS | Reactive programming / interceptor pipeline | 7.x |
| `reflect-metadata` | Decorator metadata reflection | 0.2.x |
| `iterare` | Lazy iteration utilities | 1.2.x |
| `path-to-regexp` | Route pattern matching | 8.x |
| `uid` | Unique ID generation (mixin naming) | 2.x |
| `tslib` | TypeScript helper library | 2.x |

### Data Flow: HTTP Request

1. HTTP request arrives at the platform adapter (Express/Fastify)
2. Global middleware executes in registration order
3. Module-scoped middleware executes for matching routes
4. Guards evaluate (`canActivate`) — reject returns 403 Forbidden
5. Pre-handler interceptors execute (`intercept` before `next.handle()`)
6. Pipes transform/validate parameters
7. Route handler executes
8. Post-handler interceptors process the response Observable
9. Exception filters catch any thrown errors, format the response
10. Response is sent to the client

## 2. System Requirements

| Requirement | Minimum | Recommended |
|---|---|---|
| Node.js | 20.x | Latest LTS |
| npm | 9.x | Latest |
| TypeScript | 5.0+ | 5.9+ |
| OS | Linux, macOS, Windows | Any |
| Memory | 256 MB | 512 MB+ |

### TypeScript Configuration Requirements

```json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "ES2021",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "strictNullChecks": true,
    "declaration": true,
    "sourceMap": true,
    "outDir": "./dist"
  }
}
```

> [!IMPORTANT]
> `emitDecoratorMetadata` and `experimentalDecorators` are mandatory. Without them, dependency injection based on constructor parameter types will not work.

### ESM Support

NestJS supports ECMAScript Modules (ESM) from Node.js 22+. For ESM projects, set `"type": "module"` in `package.json` and use the `load-esm` package (bundled dependency) for dynamic imports of ESM-only packages. Sample applications `34-using-esm-packages` and `35-use-esm-package-after-node22` demonstrate the pattern.

## 3. Configuration Reference

### NestFactory.create() Options

| Option | Type | Default | Description |
|---|---|---|---|
| `logger` | `LogLevel[] \| LoggerService \| false` | All levels | Controls logging output |
| `abortOnError` | `boolean` | `true` | Throw during bootstrap on init errors |
| `snapshot` | `boolean` | `false` | Enable dependency graph snapshotting |
| `preview` | `boolean` | `false` | Preview mode — no HTTP listener |
| `forceCloseConnections` | `boolean` | `false` | Force-close keep-alive connections on shutdown |
| `cors` | `boolean \| CorsOptions` | `false` | Enable CORS |
| `bodyParser` | `boolean` | `true` | Enable built-in body parsing |
| `rawBody` | `boolean` | `false` | Attach raw body buffer to request |
| `httpsOptions` | `HttpsOptions` | `undefined` | TLS/SSL configuration |

### Application Instance Methods

| Method | Description |
|---|---|
| `app.listen(port, host?)` | Start HTTP server |
| `app.getUrl()` | Get the bound URL (call after `listen()`) |
| `app.setGlobalPrefix(prefix, options?)` | Set a global route prefix |
| `app.enableVersioning(options)` | Enable API versioning |
| `app.useGlobalPipes(...pipes)` | Register global validation/transform pipes |
| `app.useGlobalGuards(...guards)` | Register global authorization guards |
| `app.useGlobalInterceptors(...interceptors)` | Register global interceptors |
| `app.useGlobalFilters(...filters)` | Register global exception filters |
| `app.useWebSocketAdapter(adapter)` | Set WebSocket adapter |
| `app.connectMicroservice(options)` | Attach a microservice transport |
| `app.startAllMicroservices()` | Start all connected microservices |
| `app.enableShutdownHooks(signals?)` | Listen for OS shutdown signals |
| `app.enableCors(options?)` | Enable CORS with options |
| `app.useLogger(logger)` | Replace the default logger |
| `app.flushLogs()` | Flush buffered log messages |
| `app.select(module)` | Navigate to a specific module context |
| `app.get(token, options?)` | Retrieve a provider instance |
| `app.resolve(token, contextId?, options?)` | Resolve a request/transient-scoped provider |
| `app.init()` | Initialize without starting the listener |
| `app.close()` | Gracefully shut down |
| `app.useBodyParser(type, options?)` | Configure body parser (Express adapter) |
| `app.setBaseViewsDir(path)` | Set MVC views directory |
| `app.setViewEngine(engine)` | Set MVC template engine |

### Environment Variables

| Variable | Effect |
|---|---|
| `NO_COLOR` | Disables ANSI color codes in logger output |
| `NEST_DEBUG` | Enables verbose DI container debug logging (shows injection resolution) |

> [!NOTE]
> `NEST_DEBUG` is extremely verbose and intended for debugging circular dependency or missing provider issues. Do not enable in production.

### Global Prefix Options

```typescript
app.setGlobalPrefix('api', {
  exclude: [
    { path: 'health', method: RequestMethod.GET },
    { path: '/', method: RequestMethod.GET },
  ],
});
```

### Versioning Options

| Property | Type | Description |
|---|---|---|
| `type` | `VersioningType` | `URI`, `HEADER`, `MEDIA_TYPE`, or `CUSTOM` |
| `defaultVersion` | `string \| string[]` | Default version for unversioned controllers |
| `header` | `string` | Header name (for `HEADER` type) |
| `key` | `string` | Media type key (for `MEDIA_TYPE` type) |
| `extractor` | `Function` | Custom version extractor (for `CUSTOM` type) |

### Module-Level Registration via APP_* Tokens

Instead of `app.useGlobal*()`, register enhancers within the DI system using special tokens:

```typescript
import { APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    { provide: APP_GUARD, useClass: AuthGuard },
    { provide: APP_PIPE, useClass: ValidationPipe },
    { provide: APP_INTERCEPTOR, useClass: LoggingInterceptor },
    { provide: APP_FILTER, useClass: AllExceptionsFilter },
  ],
})
export class AppModule {}
```

> [!TIP]
> Using `APP_*` tokens allows enhancers to participate in dependency injection (they can inject other providers). `app.useGlobal*()` registers instances outside the DI container.

## 4. Deployment & Scaling

### Production Build

```bash
npm run build        # Compile TypeScript → dist/
node dist/main.js    # Run production build
```

For monorepo workspaces:

```bash
npx tsc -b -v packages   # Build all packages
```

### Fastify Adapter (Production)

Fastify provides significantly higher throughput than Express. Switch by replacing the platform package:

```typescript
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ logger: true }),
);
await app.listen(3000, '0.0.0.0');
```

> [!WARNING]
> Fastify binds to `localhost` by default. In containerized environments, you must bind to `0.0.0.0` or the container's network interface.

### Docker Deployment

```dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["node", "dist/main.js"]
```

### Webpack Bundling

NestJS supports Webpack for bundling applications into a single file:

```bash
nest build --webpack
```

Sample `08-webpack` demonstrates this pattern with `HotModuleReplacementPlugin` for development.

### Graceful Shutdown

```typescript
const app = await NestFactory.create(AppModule);
app.enableShutdownHooks();

// Or with specific signals and options:
app.enableShutdownHooks([ShutdownSignal.SIGTERM, ShutdownSignal.SIGINT], {
  useProcessExit: true,  // Required for async loggers (e.g., Pino with transports)
});
```

**Shutdown signal lifecycle:**

1. Signal received → `onModuleDestroy()` (reverse module order)
2. `beforeApplicationShutdown(signal)` (reverse module order)
3. Server connections closed
4. `onApplicationShutdown(signal)` (reverse module order)
5. Process exits

### Hybrid Applications (HTTP + Microservices)

```typescript
const app = await NestFactory.create(AppModule);

// Attach a TCP microservice
app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: { host: '0.0.0.0', port: 3001 },
});

// Attach a Redis microservice
app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: { host: 'localhost', port: 6379 },
});

await app.startAllMicroservices();
await app.listen(3000);
```

## 5. Operations

### Logging

NestJS ships with a built-in `Logger` and `ConsoleLogger` service.

```typescript
import { Logger } from '@nestjs/common';

@Injectable()
export class CatsService {
  private readonly logger = new Logger(CatsService.name);

  findAll() {
    this.logger.log('Fetching all cats');
    this.logger.warn('This is a warning');
    this.logger.error('Something failed', stackTrace);
    this.logger.debug('Debug info');
    this.logger.verbose('Verbose info');
  }
}
```

**Log levels (in order):** `verbose`, `debug`, `log`, `warn`, `error`, `fatal`

Configure at bootstrap:

```typescript
const app = await NestFactory.create(AppModule, {
  logger: ['error', 'warn', 'log'],
});
```

> [!TIP]
> Replace the built-in logger with a production logger (Winston, Pino, etc.) by implementing `LoggerService` and calling `app.useLogger(myLogger)`.

> [!NOTE]
> The `ConsoleLogger` class can be extended for custom formatting while retaining NestJS's log level filtering logic. Unlike `Logger` (which is a static wrapper), `ConsoleLogger` is instantiable and supports dependency injection.

### Health Checks

Use `@nestjs/terminus` (separate package) for health check endpoints:

```bash
npm i @nestjs/terminus
```

```typescript
@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}
```

### Monitoring and Metrics

The `DiscoveryService` and `GraphInspector` from `@nestjs/core` provide introspection capabilities:

```typescript
import { DiscoveryService } from '@nestjs/core';

@Injectable()
export class MetricsService {
  constructor(private readonly discovery: DiscoveryService) {}

  getProviderCount(): number {
    return this.discovery.getProviders().length;
  }

  getControllerCount(): number {
    return this.discovery.getControllers().length;
  }
}
```

> [!NOTE]
> A community feature request for a native metrics module exists (nestjs/nest#967) but is not yet implemented. Use third-party packages like `@willsoto/nestjs-prometheus` or custom interceptors for request metrics.

### REPL Mode

Start an interactive REPL for debugging and exploration:

```typescript
// repl.ts
import { repl } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const replServer = await repl(AppModule);
  replServer.setupHistory('.nestjs_repl_history', (err) => {
    if (err) console.error(err);
  });
}
bootstrap();
```

```bash
npx ts-node repl.ts
```

**Built-in REPL functions:**

| Function | Description |
|---|---|
| `get(token)` | Retrieve a provider instance |
| `resolve(token)` | Resolve a request/transient-scoped provider |
| `select(module)` | Navigate to a specific module |
| `debug()` | Print all registered modules, controllers, providers |
| `methods(token)` | List available methods on a provider |
| `$(token)` | Shorthand for `get(token)` |

## 6. Performance

### Express vs. Fastify

The repository includes a benchmark suite (`tools/benchmarks/`) that compares Express and Fastify adapters:

| Framework | Relative Performance |
|---|---|
| Fastify (raw) | Baseline |
| NestJS + Fastify | ~95% of raw Fastify |
| Express (raw) | ~60-70% of Fastify |
| NestJS + Express | ~55-65% of Fastify |

> [!TIP]
> For high-throughput APIs, use `@nestjs/platform-fastify`. The Fastify adapter supports `fast-json-stringify` for schema-based response serialization, which can further improve throughput for JSON-heavy APIs.

### Injection Scopes and Performance

| Scope | Instantiation | Performance Impact |
|---|---|---|
| `DEFAULT` (singleton) | Once at startup | None — cached instance |
| `REQUEST` | Per HTTP request | Moderate — creates new instance tree per request |
| `TRANSIENT` | Per injection | High — creates new instance per consumer per request |

> [!WARNING]
> `REQUEST` scope propagates up the dependency chain. If a singleton depends on a request-scoped provider, the singleton must also become request-scoped. Design the dependency graph carefully to avoid unintended scope bubbling.

### Lazy Module Loading

Load modules on demand to reduce startup time:

```typescript
@Injectable()
export class AppService {
  constructor(private readonly loader: LazyModuleLoader) {}

  async loadReporting() {
    const { ReportingModule } = await import('./reporting/reporting.module');
    const moduleRef = await this.loader.load(() => ReportingModule);
    const service = moduleRef.get(ReportingService);
    return service.generateReport();
  }
}
```

## 7. Security

### CORS Configuration

```typescript
app.enableCors({
  origin: ['https://example.com', 'https://admin.example.com'],
  methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
  credentials: true,
  allowedHeaders: 'Content-Type,Authorization',
  exposedHeaders: 'X-Total-Count',
  maxAge: 3600,
});
```

### Helmet Integration

```bash
npm i helmet
```

```typescript
import helmet from 'helmet';

const app = await NestFactory.create(AppModule);
app.use(helmet());
```

### Rate Limiting

```bash
npm i @nestjs/throttler
```

```typescript
@Module({
  imports: [
    ThrottlerModule.forRoot({ ttl: 60, limit: 10 }),
  ],
})
export class AppModule {}
```

### Authentication Patterns

NestJS integrates with Passport.js for authentication. The sample `19-auth-jwt` demonstrates JWT authentication with:

1. **JwtStrategy** extending `PassportStrategy(Strategy)` — validates JWT tokens
2. **AuthService** — handles login logic and token generation
3. **JwtAuthGuard** extending `AuthGuard('jwt')` — protects routes
4. **Public decorator** — marks routes as public (skips authentication)

```typescript
// Public decorator pattern from sample 19
export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

### Exception Handling Security

The built-in exception layer prevents stack traces from leaking to clients in production. `HttpException` responses include only the status code and message. Enable detailed errors only in development:

```typescript
// Avoid in production
GraphQLModule.forRoot({
  includeStacktraceInErrorResponses: false,  // Default: false
});
```

> [!CAUTION]
> Never expose internal error details, stack traces, or database error messages to clients. Always catch and transform internal exceptions into appropriate HTTP exceptions with safe messages.

### File Upload Validation

Use `ParseFilePipe` with built-in validators:

```typescript
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(
  @UploadedFile(
    new ParseFilePipe({
      validators: [
        new MaxFileSizeValidator({ maxSize: 10 * 1024 * 1024 }),  // 10 MB
        new FileTypeValidator({ fileType: 'image/jpeg' }),
      ],
    }),
  )
  file: Express.Multer.File,
) {
  return { filename: file.originalname };
}
```

## 8. Developer Internals

### Repository Structure

```text
nestjs/nest/
├── packages/                    # Framework source (published to npm)
│   ├── common/                  # Shared decorators, interfaces, pipes, exceptions
│   │   ├── decorators/          # @Controller, @Injectable, @Module, @Inject, etc.
│   │   │   ├── core/            # Core decorators (DI, lifecycle, metadata)
│   │   │   ├── http/            # HTTP method + param decorators
│   │   │   └── modules/         # @Module, @Global
│   │   ├── enums/               # HttpStatus, RequestMethod, Scope, VersioningType
│   │   ├── exceptions/          # All HTTP exception classes
│   │   ├── file-stream/         # StreamableFile
│   │   ├── interfaces/          # TypeScript interfaces for the entire framework
│   │   ├── module-utils/        # ConfigurableModuleBuilder
│   │   ├── pipes/               # Built-in pipes (Validation, Parse*, File)
│   │   ├── serializer/          # ClassSerializerInterceptor
│   │   ├── services/            # Logger, ConsoleLogger
│   │   └── utils/               # Shared utilities
│   ├── core/                    # Framework engine
│   │   ├── adapters/            # AbstractHttpAdapter
│   │   ├── discovery/           # DiscoveryService, DiscoveryModule
│   │   ├── errors/              # Framework-level error classes
│   │   ├── exceptions/          # BaseExceptionFilter, ExceptionsHandler
│   │   ├── guards/              # GuardsConsumer, GuardsContextCreator
│   │   ├── helpers/             # ContextIdFactory, ExecutionContext utilities
│   │   ├── hooks/               # Lifecycle hook callers
│   │   ├── injector/            # DI container, Injector, Module, InstanceWrapper
│   │   ├── inspector/           # GraphInspector, SerializedGraph
│   │   ├── interceptors/        # InterceptorsConsumer, InterceptorsContextCreator
│   │   ├── middleware/           # MiddlewareModule, MiddlewareContainer
│   │   ├── pipes/               # PipesConsumer, PipesContextCreator
│   │   ├── repl/                # REPL mode implementation
│   │   ├── router/              # RoutesResolver, RouterExplorer, RouterModule
│   │   └── services/            # Reflector
│   ├── microservices/           # Microservice transports
│   │   ├── client/              # ClientProxy implementations per transport
│   │   ├── ctx-host/            # Transport-specific context classes
│   │   ├── decorators/          # @MessagePattern, @EventPattern, @Client, etc.
│   │   ├── deserializers/       # Message deserializers
│   │   ├── enums/               # Transport enum
│   │   ├── events/              # Event/message pattern handling
│   │   ├── exceptions/          # RpcException, microservice exception filters
│   │   ├── helpers/             # Kafka/NATS/MQTT helpers
│   │   ├── module/              # ClientsModule
│   │   ├── record-builders/     # NatsRecord, RmqRecord, MqttRecord, KafkaRecord
│   │   ├── serializers/         # Message serializers
│   │   ├── server/              # Server implementations per transport
│   │   └── utils/               # Shared microservice utilities
│   ├── platform-express/        # Express adapter
│   │   ├── adapters/            # ExpressAdapter
│   │   └── multer/              # File upload interceptors
│   ├── platform-fastify/        # Fastify adapter
│   │   ├── adapters/            # FastifyAdapter
│   │   └── decorators/          # @InjectRawBody, Fastify-specific decorators
│   ├── platform-socket.io/      # Socket.IO WebSocket adapter
│   ├── platform-ws/             # ws WebSocket adapter
│   ├── testing/                 # Test utilities (Test.createTestingModule)
│   └── websockets/              # WebSocket gateway system
│       ├── adapters/            # AbstractWsAdapter
│       ├── decorators/          # @WebSocketGateway, @SubscribeMessage, etc.
│       ├── errors/              # WS error classes
│       ├── exceptions/          # WsException, WsExceptionFilter
│       └── utils/               # Gateway metadata accessor
├── integration/                 # Integration test suites
│   ├── cors/                    # CORS integration tests
│   ├── hello-world/             # Basic HTTP integration
│   ├── hooks/                   # Lifecycle hooks tests
│   ├── injector/                # DI system tests (circular deps, scopes)
│   ├── inspector/               # Graph inspector tests
│   ├── lazy-modules/            # Lazy loading tests
│   ├── microservices/           # All transport integration tests
│   ├── mongoose/                # Mongoose integration
│   ├── nest-application/        # Application-level tests (SSE, body parser, etc.)
│   ├── repl/                    # REPL integration tests
│   ├── scopes/                  # Injection scope tests
│   ├── send-files/              # StreamableFile tests
│   ├── typeorm/                 # TypeORM integration
│   ├── versioning/              # API versioning tests
│   └── websockets/              # WebSocket integration tests
├── sample/                      # 36 example applications
├── tools/                       # Build and benchmark tools
│   ├── benchmarks/              # Express vs Fastify performance comparison
│   └── gulp/                    # Build pipeline tasks
├── lerna.json                   # Monorepo config (version: 11.1.19)
└── package.json                 # Root dependencies and scripts
```

### Architecture Deep Dive

#### Dependency Injection System

The DI system is the foundation of NestJS. It operates through these core classes:

**`NestContainer`** — The top-level container holding a `Map<string, Module>` of all registered modules. Each module is identified by a token generated from its class and dynamic metadata.

**`Module`** (internal) — Represents a single `@Module()` class. Contains three collections:
- `_providers` — Map of provider wrappers (`InstanceWrapper`)
- `_controllers` — Map of controller wrappers
- `_imports` — Set of imported module references

**`InstanceWrapper`** — Wraps a provider/controller instance with metadata: scope, injection token, resolved value, and per-context instance maps for `REQUEST`/`TRANSIENT` scopes.

**`Injector`** — The resolution engine. For each provider, it:
1. Reads constructor parameter types via `reflect-metadata`
2. Resolves each parameter's injection token
3. Looks up the matching `InstanceWrapper` in the module tree
4. Recursively instantiates dependencies
5. Caches singleton instances; creates new instances for request/transient scopes

**Injection scopes:**

| Scope | Constant | Behavior |
|---|---|---|
| Singleton | `Scope.DEFAULT` | One instance shared across all consumers (default) |
| Request | `Scope.REQUEST` | New instance per HTTP request / microservice message |
| Transient | `Scope.TRANSIENT` | New instance per injection point |

**Durable providers** (`durable: true` in `@Injectable()`) can persist across requests when used with a custom `ContextIdStrategy`.

#### Module Resolution Order

1. `NestFactory.create()` calls the `DependenciesScanner`
2. Scanner recursively traverses `imports` from the root module
3. Each module is compiled (metadata extracted, token generated)
4. The `InstanceLoader` instantiates all providers in dependency order
5. `onModuleInit` hooks fire in topological order (leaf modules first)
6. `onApplicationBootstrap` hooks fire in the same order

#### Lifecycle Hooks

| Hook Interface | Method | When |
|---|---|---|
| `OnModuleInit` | `onModuleInit()` | After provider instantiation, before app is ready |
| `OnApplicationBootstrap` | `onApplicationBootstrap()` | After all modules initialized |
| `OnModuleDestroy` | `onModuleDestroy()` | On `close()`, reverse module order |
| `BeforeApplicationShutdown` | `beforeApplicationShutdown(signal?)` | After destroy, before connections close |
| `OnApplicationShutdown` | `onApplicationShutdown(signal?)` | Final hook, after connections closed |

All hooks support async (`Promise`) return values. Modules are processed in topological distance order on init, and reverse order on shutdown.

#### Router System

The `RoutesResolver` scans all controllers and their methods:

1. Reads `PATH_METADATA` from `@Controller()` for the base path
2. Reads HTTP method metadata from `@Get()`, `@Post()`, etc.
3. Reads parameter metadata from `@Body()`, `@Param()`, etc.
4. Creates route handlers that execute the pipeline (guards → interceptors → pipes → handler)
5. Registers routes with the platform adapter

**Route parameter extraction** uses `RouteParamtypes` enum values (REQUEST=0, RESPONSE=1, NEXT=2, BODY=3, QUERY=4, PARAM=5, HEADERS=6, SESSION=7, FILE=8, FILES=9, HOST=10, IP=11, RAW_BODY=12).

#### Platform Adapters

Both adapters extend `AbstractHttpAdapter` and implement a common interface:

**`ExpressAdapter`:**
- Wraps Express 5.x
- Supports multer for file uploads (`FileInterceptor`, `FilesInterceptor`, `FileFieldsInterceptor`, `AnyFilesInterceptor`)
- Body parsing enabled by default (JSON + URL-encoded)
- Versioning supports URI, HEADER, MEDIA_TYPE, and CUSTOM types

**`FastifyAdapter`:**
- Wraps Fastify 5.x
- Uses `@fastify/multipart` for file uploads
- Uses `@fastify/middie` for Express-style middleware compatibility
- Uses `@fastify/cors` for CORS
- Uses `@fastify/static` for static file serving
- Uses `@fastify/view` for template rendering
- Supports `@fastify/formbody` for form data parsing
- Provides `@InjectRawBody()` decorator for raw body access

### Microservices Architecture

#### Transport Implementations

| Transport | Server Class | Client Class | Package |
|---|---|---|---|
| TCP | `ServerTCP` | `ClientTCP` | `@nestjs/microservices` |
| Redis | `ServerRedis` | `ClientRedis` | `@nestjs/microservices` + `ioredis` |
| NATS | `ServerNats` | `ClientNats` | `@nestjs/microservices` + `nats` |
| MQTT | `ServerMqtt` | `ClientMqtt` | `@nestjs/microservices` + `mqtt` |
| RabbitMQ | `ServerRMQ` | `ClientRMQ` | `@nestjs/microservices` + `amqplib` |
| Kafka | `ServerKafka` | `ClientKafka` | `@nestjs/microservices` + `kafkajs` |
| gRPC | `ServerGrpc` | `ClientGrpc` | `@nestjs/microservices` + `@grpc/grpc-js` |

All servers extend the abstract `Server` class. All clients extend `ClientProxy`.

#### Message Patterns

- `@MessagePattern(pattern)` — Request/response (client sends, expects a reply)
- `@EventPattern(pattern)` — Event-based (fire-and-forget, no reply)
- `@GrpcMethod(service, method)` — gRPC unary/server-streaming
- `@GrpcStreamMethod(service, method)` — gRPC client-streaming/bidirectional

#### Context Classes

Each transport provides a specialized context:

| Transport | Context Class | Key Methods |
|---|---|---|
| TCP | `TcpContext` | `getSocketRef()`, `getPattern()` |
| Redis | `RedisContext` | `getChannel()`, `getPattern()` |
| NATS | `NatsContext` | `getSubject()`, `getHeaders()` |
| MQTT | `MqttContext` | `getTopic()`, `getPacket()` |
| RabbitMQ | `RmqContext` | `getMessage()`, `getChannelRef()`, `getPattern()` |
| Kafka | `KafkaContext` | `getMessage()`, `getTopic()`, `getPartition()`, `getConsumer()`, `getProducer()`, `getHeartbeat()` |

All extend `BaseRpcContext`.

#### Record Builders

For transport-specific message metadata:

| Builder | Purpose |
|---|---|
| `NatsRecordBuilder` | Attach NATS headers to messages |
| `RmqRecordBuilder` | Attach RabbitMQ options (persistent, expiration, headers) |
| `MqttRecordBuilder` | Attach MQTT options (QoS, retain, properties) |
| `KafkaRecordBuilder` | Attach Kafka headers, key, partition |

#### ClientsModule Registration

```typescript
@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP, options: { port: 3001 } },
    ]),
    // Or async:
    ClientsModule.registerAsync([
      {
        name: 'MATH_SERVICE',
        useFactory: (config: ConfigService) => ({
          transport: Transport.TCP,
          options: { port: config.get('MATH_PORT') },
        }),
        inject: [ConfigService],
      },
    ]),
  ],
})
export class AppModule {}
```

#### Serialization Layer

Custom serializers/deserializers transform messages between wire format and application format:

| Class | Direction |
|---|---|
| `IdentitySerializer` | Passthrough (default for most transports) |
| `KafkaRequestSerializer` | Encodes Kafka message key/value/headers |
| `IncomingRequestDeserializer` | Deserializes request patterns |
| `IncomingEventDeserializer` | Deserializes event patterns |
| `KafkaRequestDeserializer` | Decodes Kafka messages |
| `NatsRequestJSONDeserializer` | Decodes NATS JSON messages |
| `NatsResponseJSONDeserializer` | Decodes NATS JSON responses |
| `MqttRecordSerializer` | Serializes MQTT records |
| `NatsRecordSerializer` | Serializes NATS records |
| `RmqRecordSerializer` | Serializes RMQ records |

### WebSocket System

The `@WebSocketGateway()` decorator registers a class as a WebSocket gateway. The `WebSocketsController` discovers all gateways, creates server instances via the configured adapter, and binds message handlers.

**Decorators:**

| Decorator | Purpose |
|---|---|
| `@WebSocketGateway(port?, options?)` | Mark class as WebSocket gateway |
| `@SubscribeMessage(event)` | Handle a specific message event |
| `@WebSocketServer()` | Inject the underlying server instance |
| `@ConnectedSocket()` | Inject the client socket |
| `@MessageBody(property?)` | Extract message body or a property |

**Gateway hooks:**

| Interface | Method |
|---|---|
| `OnGatewayInit` | `afterInit(server)` |
| `OnGatewayConnection` | `handleConnection(client, ...args)` |
| `OnGatewayDisconnect` | `handleDisconnect(client)` |

### Testing

`@nestjs/testing` provides `Test.createTestingModule()` for creating isolated test modules:

```typescript
const moduleRef = await Test.createTestingModule({
  imports: [CatsModule],
  providers: [
    { provide: CatsService, useValue: mockCatsService },
  ],
})
  .overrideProvider(CatsService)
  .useValue(mockCatsService)
  .overrideGuard(AuthGuard)
  .useValue({ canActivate: () => true })
  .compile();
```

**Override methods:**

| Method | Target |
|---|---|
| `overrideProvider(token)` | Replace a provider |
| `overrideGuard(guard)` | Replace a guard |
| `overrideInterceptor(interceptor)` | Replace an interceptor |
| `overridePipe(pipe)` | Replace a pipe |
| `overrideFilter(filter)` | Replace an exception filter |
| `overrideModule(module)` | Replace an entire module |

Each returns a builder with `.useClass()`, `.useValue()`, and `.useFactory()`.

### Code Patterns and Conventions

**Decorator pattern:** NestJS uses TypeScript decorators extensively with `reflect-metadata` for storing configuration metadata on classes and methods. All framework decorators write metadata using `Reflect.defineMetadata()`.

**Observable-based pipeline:** Interceptors use RxJS `Observable` chains. The `CallHandler.handle()` returns an `Observable` of the route handler's response, allowing operators like `map`, `tap`, `catchError`, and `timeout` to be chained.

**Commit conventions:** The repo uses Angular-style commits (`feat`, `fix`, `chore`, etc.) with scopes matching package names (`common`, `core`, `microservices`, `express`, `fastify`, `socket.io`, `ws`, `testing`, `websockets`).

**Build system:** TypeScript project references (`tsc -b`) compile all packages. Gulp tasks handle file copying, sample builds, and module relocation. Lerna manages versioning and publishing.

**Testing:** Unit tests use Mocha + Chai + Sinon. Integration tests live in `integration/` with per-feature directories. Docker Compose (`integration/docker-compose.yml`) provides Redis, NATS, MQTT, MySQL, MongoDB, RabbitMQ, ZooKeeper, and Kafka for transport integration tests.

### Key Interfaces

| Interface | Package | Purpose |
|---|---|---|
| `INestApplication` | `@nestjs/common` | HTTP application contract |
| `INestApplicationContext` | `@nestjs/common` | Standalone context contract |
| `INestMicroservice` | `@nestjs/common` | Microservice contract |
| `CanActivate` | `@nestjs/common` | Guard interface |
| `NestInterceptor` | `@nestjs/common` | Interceptor interface |
| `PipeTransform` | `@nestjs/common` | Pipe interface |
| `ExceptionFilter` | `@nestjs/common` | Exception filter interface |
| `NestMiddleware` | `@nestjs/common` | Middleware interface |
| `OnModuleInit` | `@nestjs/common` | Lifecycle hook |
| `OnApplicationBootstrap` | `@nestjs/common` | Lifecycle hook |
| `OnModuleDestroy` | `@nestjs/common` | Lifecycle hook |
| `BeforeApplicationShutdown` | `@nestjs/common` | Lifecycle hook |
| `OnApplicationShutdown` | `@nestjs/common` | Lifecycle hook |
| `Type<T>` | `@nestjs/common` | Class constructor type |
| `DynamicModule` | `@nestjs/common` | Dynamic module metadata |
| `ModuleMetadata` | `@nestjs/common` | Static module metadata |
| `CustomDecorator` | `@nestjs/common` | Return type of `SetMetadata()` |

### ConfigurableModuleBuilder

Generates `forRoot()`, `forRootAsync()`, `MODULE_OPTIONS_TOKEN`, and `ConfigurableModuleAsyncOptions` for dynamic modules:

```typescript
import { ConfigurableModuleBuilder } from '@nestjs/common';

export interface HttpModuleOptions {
  baseUrl: string;
  timeout?: number;
}

export const {
  ConfigurableModuleClass,
  MODULE_OPTIONS_TOKEN,
  OPTIONS_TYPE,
  ASYNC_OPTIONS_TYPE,
} = new ConfigurableModuleBuilder<HttpModuleOptions>()
  .setClassMethodName('forRoot')
  .setExtras({ isGlobal: false }, (definition, extras) => ({
    ...definition,
    global: extras.isGlobal,
  }))
  .build();
```

### Reflector Service

The `Reflector` class (from `@nestjs/core`) reads metadata set by `@SetMetadata()`:

```typescript
// Define
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);

// Use
@Roles('admin')
@Get()
findAll() {}

// Read in guard
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) return true;
    const request = context.switchToHttp().getRequest();
    return roles.includes(request.user?.role);
  }
}
```

**Reflector methods:**

| Method | Description |
|---|---|
| `get(key, target)` | Get metadata from a single target |
| `getAll(key, targets)` | Get metadata from multiple targets |
| `getAllAndMerge(key, targets)` | Merge metadata arrays from multiple targets |
| `getAllAndOverride(key, targets)` | Get first non-undefined metadata |

## 9. Integration Points

### Database Integrations

NestJS provides official wrappers for database ORMs as separate packages:

| Package | ORM | Database Types |
|---|---|---|
| `@nestjs/typeorm` | TypeORM | MySQL, PostgreSQL, SQLite, SQL Server, Oracle |
| `@nestjs/mongoose` | Mongoose | MongoDB |
| `@nestjs/sequelize` | Sequelize | MySQL, PostgreSQL, SQLite, SQL Server |

Each provides `forRoot()` / `forRootAsync()` and `forFeature()` patterns for module-level configuration.

### GraphQL

| Package | Purpose |
|---|---|
| `@nestjs/graphql` | GraphQL module with code-first and schema-first approaches |
| `@nestjs/apollo` | Apollo Server driver |
| `@nestjs/mercurius` | Mercurius (Fastify-native) driver |

**Federation support:** Samples `31-graphql-federation-code-first` and `32-graphql-federation-schema-first` demonstrate Apollo Federation with gateway + subgraph patterns.

### Caching

```typescript
import { CacheModule } from '@nestjs/cache-manager';

@Module({
  imports: [CacheModule.register({ ttl: 5, max: 100 })],
})
export class AppModule {}
```

Use `@UseInterceptors(CacheInterceptor)` for automatic GET response caching.

### Task Scheduling

```bash
npm i @nestjs/schedule
```

```typescript
import { Cron, Interval, Timeout } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  @Cron('0 */5 * * * *')
  handleCron() { /* every 5 minutes */ }

  @Interval(10000)
  handleInterval() { /* every 10 seconds */ }

  @Timeout(5000)
  handleTimeout() { /* once after 5 seconds */ }
}
```

### Event Emitter

```bash
npm i @nestjs/event-emitter
```

```typescript
import { EventEmitter2 } from '@nestjs/event-emitter';

@Injectable()
export class OrdersService {
  constructor(private eventEmitter: EventEmitter2) {}

  create(order: Order) {
    this.eventEmitter.emit('order.created', new OrderCreatedEvent(order));
  }
}

@Injectable()
export class OrderCreatedListener {
  @OnEvent('order.created')
  handleOrderCreatedEvent(event: OrderCreatedEvent) {
    // Handle event
  }
}
```

### Queues

```bash
npm i @nestjs/bull bull
```

```typescript
@Module({
  imports: [
    BullModule.forRoot({
      redis: { host: 'localhost', port: 6379 },
    }),
    BullModule.registerQueue({ name: 'audio' }),
  ],
})
export class AppModule {}
```

### Docker Compose for Integration Testing

The repository's `integration/docker-compose.yml` provisions all external services needed for transport tests:

| Service | Image | Port |
|---|---|---|
| Redis | `redis` | 6379 |
| NATS | `nats` | 4222, 8222 |
| MQTT | `eclipse-mosquitto` | 1883, 9001 |
| MySQL | `mysql:9.6.0` | 3306 |
| MongoDB | `mongo:latest` | 27017 |
| RabbitMQ | `rabbitmq:management` | 5672, 15672 |
| ZooKeeper | `confluentinc/cp-zookeeper:7.9.6` | 2181 |
| Kafka | `confluentinc/cp-kafka:8.2.0` | 9092, 29092 |

```bash
docker-compose -f integration/docker-compose.yml up -d
npm run test:integration
docker-compose -f integration/docker-compose.yml down
```

> [!NOTE]
> KafkaJS, the Kafka client used by NestJS, appears to be no longer actively maintained (nestjs/nest#13223). Monitor for potential migration to an alternative client library.

### Build Scripts

| Script | Purpose |
|---|---|
| `npm run build` | Compile all packages (tsc -b) |
| `npm run build:prod` | Clean build for release |
| `npm run test` | Run unit tests (Mocha) |
| `npm run test:integration` | Run integration tests |
| `npm run test:cov` | Run tests with coverage |
| `npm run test:docker:up` | Start Docker services for integration tests |
| `npm run test:docker:down` | Stop Docker services |
| `npm run lint` | Lint packages, integration, and spec files |
| `npm run format` | Format with Prettier |
| `npm run publish` | Build and publish via Lerna |

### Contributing

The repository uses:
- **Commit format:** Angular-style (`feat(core): add feature`, `fix(microservices): fix bug`)
- **Linting:** ESLint with Prettier integration
- **Pre-commit:** Husky + lint-staged (auto-formats `.ts` and `.json` files)
- **CI:** CircleCI for build/test/lint
- **Code coverage:** nyc + Coveralls
- **Monorepo management:** Lerna (version 9.x)

### Known Issues

| Issue | Status | Impact |
|---|---|---|
| nestjs/nest#13223 | Open | KafkaJS maintenance concerns |
| nestjs/nest#16257 | Open | Nested transient providers not isolated in static context |
| nestjs/nest#11802 | Open | Fastify middleware route matching with plugins |
| nestjs/nest#14590 | Open | Concurrent Kafka topic consumption |
| nestjs/nest#6771 | Open | Socket.IO `forwardEventNameAs` option for IoAdapter |
| nestjs/nest#1953 | Open | gRPC exception filter support |
| nestjs/nest#967 | Open | Native metrics module feature request |

---

_Generated May 2026 from nestjs/nest at 4b6420b. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
