@nam088/nestjs-configx
v0.1.1
Published
Typed, validated, multi-source configuration for NestJS (>=10).
Maintainers
Readme
@nam088/nestjs-configx
Typed, validated, multi-source configuration for NestJS (>=10) powered by Zod.
- Type-safe access: Strongly-typed getters with autocomplete for your schema paths
- Validation at startup: Parse and validate config before your app runs
- Multiple sources (extensible): Loads from environment by default, easy to extend
- Developer-friendly utils: Helpers for boolean, number, JSON, enums, namespacing, and caching
Installation
npm install @nam088/nestjs-configx zodPeer dependencies:
@nestjs/commonand@nestjs/core(>=10 <12)- Node.js >= 18
Quick start
- Define your configuration schema with Zod
// config.schema.ts
import { z } from 'zod';
export const ConfigSchema = z.object({
app: z.object({
name: z.string().default('my-app'),
env: z.enum(['development', 'test', 'production']).default('development'),
port: z.coerce.number().int().min(1).max(65535).default(3000),
}),
database: z.object({
url: z.string().url(),
ssl: z.coerce.boolean().optional(),
}),
});
export type Config = z.infer<typeof ConfigSchema>;- Register the module
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigxModule } from '@nam088/nestjs-configx';
import { ConfigSchema } from './config.schema';
@Module({
imports: [
ConfigxModule.forRoot({
schema: ConfigSchema,
isGlobal: true,
// optional
// envFilePath: ['.env', `.env.${process.env.NODE_ENV}`],
// ignoreEnvFile: false,
// cache: true,
}),
],
})
export class AppModule {}- Read configuration anywhere
import { Injectable } from '@nestjs/common';
import { ConfigxService } from '@nam088/nestjs-configx';
import type { Config } from './config.schema';
@Injectable()
export class AppService {
constructor(private readonly config: ConfigxService) {}
getPort(): number {
// Strongly-typed path access when using generics
return this.config.get<number>('app.port') ?? 3000;
}
getDbUrl(): string {
return this.config.getOrThrow('database.url');
}
}Or inject via decorator:
import { Injectable } from '@nestjs/common';
import { InjectConfigx, ConfigxService } from '@nam088/nestjs-configx';
@Injectable()
export class Example {
constructor(@InjectConfigx() private readonly cfg: ConfigxService) {}
}.env example
APP_NAME=my-app
APP_ENV=production
APP_PORT=8080
DATABASE_URL=https://example.com
DATABASE_SSL=trueBy default, variables are loaded from .env (if present) and expanded (dotenv + dotenv-expand). You can customize with envFilePath or disable with ignoreEnvFile.
Async configuration
ConfigxModule.forRootAsync({
inject: [SomeService],
useFactory: (svc: SomeService) => ({
schema: ConfigSchema,
isGlobal: true,
envFilePath: svc.getEnvFiles(),
cache: true,
}),
});API
Module
ConfigxModule.forRoot(options)ConfigxModule.forRootAsync(options)
options:
schema(required): Zod schemaisGlobal(default: false)envFilePath?: string | string[](default: '.env')ignoreEnvFile?: boolean(default: false)cache?: boolean(default: false) — enablesget()result caching per path
Service: ConfigxService
get<T>(path: string): T | undefinedgetOrThrow<T>(path: string, message?: string): TgetString(path, defaultValue?)getNumber(path, defaultValue?)getBoolean(path, defaultValue?)getJSON<T>(path, defaultValue?)getEnum<T extends string>(path, values: readonly T[], defaultValue?)getAll<T = Record<string, unknown>>(): T— returns the validated treehas(path: string): booleanset<T>(path: string, value: T): void— updates in-memory validated config andprocess.env[path]namespaced(prefix: string)— returns the same getters scoped by prefixrefresh(): Promise<void>— reloads from source and re-validates (clears cache when enabled)
Type-safe path access is supported via generics when you thread your schema shape through your service typing.
Examples
See a runnable example in examples/basic-use.
Scripts
npm run build # build to dist
npm run test # unit tests
npm run test:cov # coverage
npm run lint # eslint
npm run format # prettierLicense
MIT © Nam088
