Skip to main content

How to Integrate Feature Flags in NestJS

· 8 min read
Chavez Harris
Inspiration does exist, but it must find you writing code.

Software development can be challenging, but deploying and managing new features shouldn't be. With feature flags, you can rest assured that your updates and new features are delivered safely with minimal risk. In this guide, I'll show you how to integrate a feature flag into a NestJS application.

How to use feature flags in NestJS cover

Before we dive in, let's take a moment to understand how feature flags work.

How Do Feature Flags Work?

Feature flags, sometimes called feature toggles or feature switches, are mechanisms used to conditionally hide or display features in an application. A feature flag typically holds a Boolean value that your code can use to enable or disable a feature. Feature flag evaluation can also take into account an evaluation context, such as user role or request data, to enable user targeting.

With feature flags, developers can include an unfinished new feature in the codebase and then toggle it on with just a click.

info

To learn more about feature flags and how they can benefit your development workflow, click here.

Sample App

To show you a practical example of feature flags in action, I've created a demo auto dealership website using NestJS. The new feature is a fuel mileage calculator to be displayed under the banner on the home page. To put this feature behind a flag, I'll use ConfigCat feature flag system. ConfigCat provides a wide range of SDKs and integrations, making it easy to effectively manage your own feature flags across your tech stack.

To follow along, check if you have the following:

Prerequisites

Sample App Setup

  1. Create a new directory for the project. You can name it feature-flags-in-nestjs-sample.

  2. Install the Nest CLI tool, and create a new NestJS project with the following commands:

npm i -g @nestjs/cli
nest new feature-flags-in-nestjs-sample

When prompted, select npm as the package manager and give it a moment to complete.

  1. Launch the NestJS app and access it in your browser at http://localhost:3000/. You should see a "Hello World!" message displayed.
npm run start:dev
  1. Lets use the Handlebars templating engine to build the frontend. Install it with the following command:
npm install --save hbs
  1. To configure the NestJS app to use the Handlebars templating engine, update the src/main.ts file as shown below:
src/main.ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);

app.useStaticAssets(join(__dirname, '../', 'public'));
app.setBaseViewsDir(join(__dirname, '../', 'views'));
app.setViewEngine('hbs');

await app.listen(process.env.PORT ?? 3000);
console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();
  1. Create a new folder called views in the root directory, then create an index.hbs file inside it for the home page, using the content from here.

  2. Update the src/app.controller.ts file as shown below. This code instructs the app to call the App Service (src/app.service.ts) to get the view name for rendering. Later, we’ll add some future feature flag logic to it.

src/app.controller.ts
import { Controller, Get, Res, Req } from '@nestjs/common';
import { AppService } from './app.service';
import type { Response, Request } from 'express';

@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly configCatService: ConfigCatService,
) {}

@Get('/*')
root(@Req() req: Request, @Res() res: Response) {
const viewName = this.appService.getViewName(req);
res.render(viewName);
}
}
  1. In the src/app.service.ts file, I've added a URL to view map. The getViewName function in the previous step uses the map to get the view based on the request URL.
src/app.service.ts
import { Injectable } from '@nestjs/common';
import type { Request } from 'express';

@Injectable()
export class AppService {
private readonly urlToViewMap: Record<string, string> = {
'/': 'index',
};
getViewName(req: Request): string {
return this.urlToViewMap[req.url] || 'not-found';
}
}

Launch the app and go to http://localhost:3000/ to view the home page. You'll see the text Fuel Per Mileage Calculator is coming soon. Stay tuned! at the bottom.

Sample app with feature and text

Let's use a ConfigCat feature flag to display the mileage calculator when the flag is enabled and show the text when it is disabled.

Setup and Integrate the Feature Flag

  1. In your ConfigCat dashboard, create a feature flag with the following feature name and key:
FieldValue
nameMileage Calculator Feature
keymileageCalculatorFeature
  1. NestJS is a server-side framework, so I'll install ConfigCat's Node SDK:
npm i @configcat/sdk
  1. I'll create a custom ConfigCat feature service that I can import and use in other files. In the src directory, create a configcat.service.ts file with the following content:
src/configcat.service.ts
import { Injectable } from '@nestjs/common';
import * as configcat from '@configcat/sdk';
import type { IConfigCatClient } from '@configcat/sdk';

@Injectable()
export class ConfigCatService {
private readonly configCatClient: IConfigCatClient;

constructor() {
this.configCatClient = configcat.getClient('YOUR-CONFIGCAT-SDK-KEY');
}

async getValue(key: string, defaultValue: boolean): Promise<boolean> {
return this.configCatClient.getValueAsync(key, defaultValue);
}
}
  1. I'll update the src/app.controller.ts file. I'll use the feature service to query the value of the feature flag and then pass it to the view.
src/app.controller.ts
import { Controller, Get, Res, Req } from '@nestjs/common';
import { AppService } from './app.service';
import type { Response, Request } from 'express';
import { ConfigCatService } from './configcat.service';

@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly configCatService: ConfigCatService,
) {}

@Get('/*')
async root(@Req() req: Request, @Res() res: Response) {
const viewName = this.appService.getViewName(req);

// Get the value of the feature flag
const isMileageCalculatorFeatureEnabled =
await this.configCatService.getValue('mileageCalculatorFeature', false);

res.render(viewName, {
isMileageCalculatorFeatureEnabled, // Pass the value to the view
});
}
}
  1. In the index.hbs file, I'll use the isMileageCalculatorFeatureEnabled variable passed from the controller with conditional logic to render the mileage calculator feature, as shown below:
index.hbs
  <div class='container'>
{{#if isMileageCalculatorFeatureEnabled }}
<!-- Render the mileage calculator feature -->
<div class='mileage-calculator'>
<h2>Fuel Per Mileage Calculator</h2>
<div class='calculator'>
<!-- HTML code for the calculator -->
</div>
</div>
{{else}}
<!-- Else, render the following text -->
<p>
Fuel Per Mileage Calculator is coming soon. Stay tuned!
</p>
{{/if}}
</div>

App Demo

  1. When the feature flag is on in the ConfigCat dashboard, the home page should look like this:
Sample app - flag on
  1. When the feature flag is switched off, the following text will be displayed on the home page:
Sample app - flag off

By default, the ConfigCat client SDK uses AutoPoll to check the status of the feature flag every 60 seconds, eliminating the need to restart the app. You can also adjust this interval to your choosing. Learn more about it here.

Summary

In this guide, we covered how to integrate feature flags into a NestJS application using ConfigCat's feature management service.

Feature flag services like ConfigCat make it easy to manage and release new features from a central dashboard, allowing you to toggle features on and off without redeploying your app.

Beyond NestJS, ConfigCat provides a wide range of SDKs and integrations to integrate feature flags across your technology stack. To learn more, check out ConfigCat's official documentation.

For more posts like this and the latest updates, follow ConfigCat on X, Facebook, LinkedIn, and GitHub.