
Configuration
- 2 installs
- 1 repo stars
- Updated January 2, 2026
- ramziddin/ccplugins
Reference for NestJS configuration management with @nestjs/config: environment variables, validation, namespaces, and custom config files.
About
Explains how to manage application settings in NestJS using the @nestjs/config module, including env vars, Joi validation, and type-safe access. A developer uses it to organize environment-specific configuration.
- Loads env vars via ConfigService from .env files
- Supports Joi validation and configuration namespaces
Configuration by the numbers
- 2 all-time installs (skills.sh)
- Ranked #3,774 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ramziddin/ccplugins --skill configurationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 1 |
| Last updated | January 2, 2026 |
| Repository | ramziddin/ccplugins ↗ |
What it does
Reference for NestJS configuration management with @nestjs/config: environment variables, validation, namespaces, and custom config files.
Files
NestJS Configuration
When to Use This Skill
Use this skill when:
- Managing environment variables
- Setting up application configuration
- Validating configuration values
- Creating custom configuration files
- Working with different environments (dev, staging, production)
- Organizing configuration namespaces
- Using type-safe configuration
What is Configuration?
The @nestjs/config module provides a ConfigService that loads environment variables from .env files and provides a centralized way to access configuration throughout your application.
Installation
npm install @nestjs/configFor validation:
npm install joi
npm install --save-dev @types/joiBasic Setup
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
],
})
export class AppModule {}Key Points:
isGlobal: true- Makes ConfigModule available everywhere- Automatically loads
.envfile from root directory - Environment variables accessible via
ConfigService
Using ConfigService
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class AppService {
constructor(private configService: ConfigService) {}
getDatabaseUrl(): string {
return this.configService.get<string>('DATABASE_URL');
}
getPort(): number {
return this.configService.get<number>('PORT', 3000);
}
// Non-nullable value (throws if not found)
getApiKey(): string {
return this.configService.getOrThrow<string>('API_KEY');
}
}Environment File (.env)
# .env
NODE_ENV=development
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
PORT=3000
API_KEY=secret-key
JWT_SECRET=jwt-secret-keyCustom Configuration Files
Create namespaced configuration:
// config/database.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('database', () => ({
host: process.env.DATABASE_HOST || 'localhost',
port: parseInt(process.env.DATABASE_PORT, 10) || 5432,
username: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
}));// config/app.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('app', () => ({
port: parseInt(process.env.PORT, 10) || 3000,
environment: process.env.NODE_ENV || 'development',
apiPrefix: process.env.API_PREFIX || 'api',
}));Register custom configurations:
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import databaseConfig from './config/database.config';
import appConfig from './config/app.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [databaseConfig, appConfig],
}),
],
})
export class AppModule {}Access namespaced configuration:
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class DatabaseService {
constructor(private configService: ConfigService) {}
getConnectionOptions() {
const host = this.configService.get<string>('database.host');
const port = this.configService.get<number>('database.port');
// Alternative: get entire namespace
const dbConfig = this.configService.get('database');
return dbConfig;
}
}Configuration Validation
Using Joi for schema validation:
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
validationSchema: Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'production', 'test')
.default('development'),
PORT: Joi.number().default(3000),
DATABASE_URL: Joi.string().required(),
API_KEY: Joi.string().required(),
JWT_SECRET: Joi.string().required(),
JWT_EXPIRATION: Joi.string().default('1h'),
}),
validationOptions: {
allowUnknown: true,
abortEarly: false,
},
}),
],
})
export class AppModule {}Validation Options:
allowUnknown- Allow environment variables not in schemaabortEarly- Stop validation on first error (false = report all errors)
Custom Validation with class-validator
import { plainToInstance } from 'class-transformer';
import { IsEnum, IsNumber, IsString, validateSync } from 'class-validator';
enum Environment {
Development = 'development',
Production = 'production',
Test = 'test',
}
class EnvironmentVariables {
@IsEnum(Environment)
NODE_ENV: Environment;
@IsNumber()
PORT: number;
@IsString()
DATABASE_URL: string;
@IsString()
API_KEY: string;
}
function validate(config: Record<string, unknown>) {
const validatedConfig = plainToInstance(
EnvironmentVariables,
config,
{ enableImplicitConversion: true },
);
const errors = validateSync(validatedConfig, {
skipMissingProperties: false,
});
if (errors.length > 0) {
throw new Error(errors.toString());
}
return validatedConfig;
}
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
validate,
}),
],
})
export class AppModule {}Configuration Options
ConfigModule.forRoot({
// Make module global
isGlobal: true,
// Custom .env file path
envFilePath: '.env.development',
// Multiple env files (priority order)
envFilePath: ['.env.local', '.env'],
// Ignore .env file
ignoreEnvFile: true,
// Load custom configuration files
load: [databaseConfig, appConfig],
// Validation schema
validationSchema: Joi.object({...}),
// Validation options
validationOptions: {
allowUnknown: true,
abortEarly: false,
},
// Custom validate function
validate: (config) => config,
// Expand environment variables
expandVariables: true,
// Cache configuration values
cache: true,
})Type-Safe Configuration
Create configuration interface:
// config/configuration.interface.ts
export interface DatabaseConfig {
host: string;
port: number;
username: string;
password: string;
database: string;
}
export interface AppConfig {
port: number;
environment: string;
apiPrefix: string;
}
export interface Configuration {
database: DatabaseConfig;
app: AppConfig;
}Use with ConfigService:
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { DatabaseConfig } from './config/configuration.interface';
@Injectable()
export class DatabaseService {
constructor(private configService: ConfigService) {}
getConfig(): DatabaseConfig {
return this.configService.get<DatabaseConfig>('database');
}
}Async Configuration
Load configuration asynchronously:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
DatabaseModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
host: configService.get('database.host'),
port: configService.get('database.port'),
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}Conditional Module Loading
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
],
providers: [
{
provide: 'CACHE_MODULE',
useFactory: (configService: ConfigService) => {
const cacheEnabled = configService.get<boolean>('CACHE_ENABLED');
return cacheEnabled ? CacheModule : null;
},
inject: [ConfigService],
},
],
})
export class AppModule {}Environment-Specific Files
const envFilePath = `.env.${process.env.NODE_ENV || 'development'}`;
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath,
}),
],
})
export class AppModule {}Files structure:
.env.development.env.staging.env.production.env.test
Expanding Variables
Enable variable expansion in .env files:
# .env
DATABASE_USER=postgres
DATABASE_PASSWORD=secret
DATABASE_NAME=mydb
DATABASE_URL=postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@localhost:5432/${DATABASE_NAME}@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
expandVariables: true,
}),
],
})
export class AppModule {}Testing Configuration
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigModule, ConfigService } from '@nestjs/config';
describe('ConfigService', () => {
let configService: ConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
ignoreEnvFile: true,
load: [
() => ({
DATABASE_URL: 'postgresql://localhost:5432/test',
PORT: 3000,
}),
],
}),
],
}).compile();
configService = module.get<ConfigService>(ConfigService);
});
it('should get database URL', () => {
expect(configService.get('DATABASE_URL')).toBe(
'postgresql://localhost:5432/test',
);
});
});Best Practices
1. Use validation - Always validate configuration on startup 2. Type safety - Use TypeScript interfaces for configuration 3. Default values - Provide sensible defaults 4. Required values - Use getOrThrow() for critical config 5. Namespace configuration - Organize related configs together 6. Don't commit .env - Add to .gitignore 7. Document variables - Provide .env.example file 8. Use secrets management - For production sensitive data 9. Cache configuration - Enable caching for performance 10. Global module - Set isGlobal: true for convenience
Common Patterns
Database Configuration
import { registerAs } from '@nestjs/config';
export default registerAs('database', () => ({
type: 'postgres',
host: process.env.DATABASE_HOST,
port: parseInt(process.env.DATABASE_PORT, 10),
username: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
synchronize: process.env.NODE_ENV === 'development',
logging: process.env.NODE_ENV === 'development',
}));JWT Configuration
import { registerAs } from '@nestjs/config';
export default registerAs('jwt', () => ({
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRATION || '1h',
refreshSecret: process.env.JWT_REFRESH_SECRET,
refreshExpiresIn: process.env.JWT_REFRESH_EXPIRATION || '7d',
}));Feature Flags
import { registerAs } from '@nestjs/config';
export default registerAs('features', () => ({
enableCache: process.env.ENABLE_CACHE === 'true',
enableLogging: process.env.ENABLE_LOGGING === 'true',
enableMetrics: process.env.ENABLE_METRICS === 'true',
}));