Skip to content

NestJS Config Module

@nestjs/config is Nest's official configuration package. This lesson shows loading .env files, injecting ConfigService, and structuring namespaced config.

Registering ConfigModule Globally

Import ConfigModule.forRoot({ isGlobal: true }) once in AppModule so ConfigService is available everywhere without re-importing. It loads .env by default and merges values into process.env.

ConfigModule.forRoot({
  isGlobal: true,
  envFilePath: ['.env.local', '.env'],
  validationSchema: Joi.object({
    NODE_ENV: Joi.string().valid('development', 'production', 'test').required(),
    PORT: Joi.number().default(3000),
    JWT_SECRET: Joi.string().min(16).required(),
  }),
})

A validation schema fails fast at boot when required variables are missing or invalid.

Reading Values With ConfigService

@Injectable()
export class MailService {
  constructor(private config: ConfigService) {}

  get fromAddress() {
    return this.config.get<string>('MAIL_FROM');
  }
}
  • config.get('KEY') reads an environment variable or custom config property.
  • config.getOrThrow('KEY') throws if the key is missing.
  • load factories can return nested config objects for namespacing.
  • ignoreEnvFile: true is useful in production when the platform injects env vars.

ConfigModule Cheatsheet

Options and APIs you will use most.

API Purpose
ConfigModule.forRoot() Bootstrap env loading
isGlobal: true Make ConfigService available app-wide
envFilePath Choose which .env files to load
validationSchema Validate env at startup
ConfigService.get() Read a config value
registerAs('db', factory) Namespace custom config

Namespaced Configuration

Use registerAs to create database or jwt namespaces, then inject them with typed helpers for cleaner access than flat env keys everywhere.

export default registerAs('database', () => ({
  url: process.env.DATABASE_URL,
  ssl: process.env.DB_SSL === 'true',
}));

Feeding Other Modules

TypeORM, JWT, and Mail modules commonly use registerAsync factories that inject ConfigService to read secrets at runtime.

Common Mistakes

  • Forgetting isGlobal: true and re-importing ConfigModule in every feature.
  • Not validating env vars and discovering missing secrets only in production traffic.
  • Committing a filled .env file with real credentials.
  • Assuming .env files exist in container/prod environments where only real env vars are set.

Key Takeaways

  • ConfigModule loads env files and exposes ConfigService for DI.
  • Validate configuration at boot with a schema.
  • Use namespaced registerAs factories for structured config.
  • Wire other Nest modules via registerAsync + ConfigService.

Pro Tip

Prefer getOrThrow for secrets required at runtime so a missing JWT secret fails immediately instead of signing tokens with undefined.