Skip to main content
Practice Problems

How to manage configuration in NestJS with configmodule?

Configuration Management in NestJS

NestJS provides @nestjs/config — a module that loads environment variables from .env files and exposes them via a type-safe ConfigService.


Setup

bash
npm install @nestjs/config
typescript
// app.module.ts import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, // no need to import in every module envFilePath: '.env', cache: true, // cache values for performance }), ], }) export class AppModule {}

Using ConfigService

typescript
import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; @Injectable() export class DatabaseService { constructor(private configService: ConfigService) {} getConnectionString(): string { const host = this.configService.get<string>('DB_HOST'); const port = this.configService.get<number>('DB_PORT', 5432); // default 5432 const name = this.configService.get<string>('DB_NAME'); return `postgres://${host}:${port}/${name}`; } }

Typed Configuration (Namespaced)

typescript
// config/database.config.ts import { registerAs } from '@nestjs/config'; export default registerAs('database', () => ({ host: process.env.DB_HOST || 'localhost', port: parseInt(process.env.DB_PORT || '5432', 10), name: process.env.DB_NAME || 'mydb', password: process.env.DB_PASS, })); // app.module.ts import databaseConfig from './config/database.config'; ConfigModule.forRoot({ isGlobal: true, load: [databaseConfig], }) // Usage: const dbHost = this.configService.get<string>('database.host'); const dbPort = this.configService.get<number>('database.port');

Environment Validation with Joi

bash
npm install joi
typescript
import * as Joi from 'joi'; ConfigModule.forRoot({ isGlobal: true, validationSchema: Joi.object({ NODE_ENV: Joi.string().valid('development', 'production', 'test').required(), PORT: Joi.number().default(3000), DB_HOST: Joi.string().required(), DB_PORT: Joi.number().default(5432), DB_USER: Joi.string().required(), DB_PASS: Joi.string().required(), DB_NAME: Joi.string().required(), JWT_SECRET: Joi.string().min(32).required(), }), validationOptions: { allowUnknown: true, abortEarly: false, // show all errors at once }, })

If validation fails, the app refuses to start — catching missing env vars early.


Using Config in forRoot() (e.g., TypeORM)

typescript
TypeOrmModule.forRootAsync({ imports: [ConfigModule], useFactory: (config: ConfigService) => ({ type: 'postgres', host: config.get('DB_HOST'), port: config.get<number>('DB_PORT'), username: config.get('DB_USER'), password: config.get('DB_PASS'), database: config.get('DB_NAME'), autoLoadEntities: true, synchronize: config.get('NODE_ENV') !== 'production', }), inject: [ConfigService], })

Multiple .env Files

typescript
ConfigModule.forRoot({ envFilePath: [ `.env.${process.env.NODE_ENV}.local`, `.env.${process.env.NODE_ENV}`, '.env.local', '.env', ], })

Summary

Use ConfigModule.forRoot({ isGlobal: true }) to load .env once and make ConfigService available everywhere. Add validationSchema with Joi to validate required variables at startup. Use registerAs() for typed, namespaced config objects.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems