> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.clubedge.live/llms.txt
> Use this file to discover all available pages before exploring further.

# NestJS SDK

> Integrate feature flags into NestJS applications using the built-in module with dependency injection.

The NestJS SDK (`@clubedge/feature-flags-nestjs`) provides a `FeatureFlagsModule` that registers a singleton `FeatureFlagsClient` in the NestJS dependency injection container. It wraps `@clubedge/feature-flags-sdk-core`.

## Requirements

* NestJS 11+
* Node.js 18+

## Installation

```bash theme={null}
pnpm add @clubedge/feature-flags-nestjs
```

## Registration

Register the module in your root `AppModule`:

```typescript theme={null}
// app.module.ts
import { Module } from '@nestjs/common';
import { FeatureFlagsModule } from '@clubedge/feature-flags-nestjs';

@Module({
  imports: [
    FeatureFlagsModule.forRoot({
      sdkKey: process.env.FF_SDK_KEY!,
      baseUrl: 'https://flags.clubedge.live',
      pollIntervalMs: 30_000,
    }),
  ],
})
export class AppModule {}
```

The module accepts the same options as any `FeatureFlagsClient` configuration:

| Option            | Type     | Required | Default                 |
| ----------------- | -------- | -------- | ----------------------- |
| `sdkKey`          | `string` | Yes      | —                       |
| `baseUrl`         | `string` | No       | `http://localhost:3000` |
| `pollIntervalMs`  | `number` | No       | `30000`                 |
| `cacheTtlSeconds` | `number` | No       | `60000`                 |

See [SDK configuration](/feature-flags/reference/sdk-config) for the full reference including `retries`, `retryDelayMs`, `logger`, and `eventEmitter`.

## Injection

Inject the client into any service, controller, or provider using the `FEATURE_FLAGS_CLIENT` token:

```typescript theme={null}
// dashboard.controller.ts
import { Controller, Get, Inject, Req } from '@nestjs/common';
import { FEATURE_FLAGS_CLIENT } from '@clubedge/feature-flags-nestjs';
import { FeatureFlagsClient } from '@clubedge/feature-flags-sdk-core';

@Controller('dashboard')
export class DashboardController {
  constructor(
    @Inject(FEATURE_FLAGS_CLIENT) private readonly flags: FeatureFlagsClient,
  ) {}

  @Get()
  getDashboard(@Req() req: Request) {
    const enabled = this.flags.isEnabled('new_dashboard', {
      userId: req.user.id,
      tenantId: req.user.tenantId,
    });
    return enabled ? { view: 'new' } : { view: 'old' };
  }
}
```

## Lifecycle management

The module calls `client.initialize()` automatically on `onModuleInit`. To ensure clean shutdown during NestJS termination:

```typescript theme={null}
// flags-lifecycle.service.ts
import { Injectable, OnModuleDestroy, Inject } from '@nestjs/common';
import { FEATURE_FLAGS_CLIENT } from '@clubedge/feature-flags-nestjs';
import { FeatureFlagsClient } from '@clubedge/feature-flags-sdk-core';

@Injectable()
export class FlagsLifecycleService implements OnModuleDestroy {
  constructor(
    @Inject(FEATURE_FLAGS_CLIENT) private readonly client: FeatureFlagsClient,
  ) {}

  onModuleDestroy() {
    this.client.shutdown();
  }
}
```

Don't forget to register `FlagsLifecycleService` in your module's `providers` array.

<Warning>
  The `FeatureFlagsModule` currently only exposes `forRoot()` — there is no async/factory registration method. Pass environment variables directly into `forRoot()`.
</Warning>

<Warning>
  The SDK pre-evaluates flags at config-fetch time with empty context — `isEnabled()` returns the cached result regardless of the `context` argument. For per-user targeting, use [Direct HTTP](/feature-flags/reference/evaluation-api).
</Warning>

## Next steps

* [SDK configuration reference](/feature-flags/reference/sdk-config)
* [Evaluation API](/feature-flags/reference/evaluation-api)
* [Admin API](/feature-flags/reference/admin-api)
