| title | Use with NestJS |
|---|---|
| description | Validate and type environment variables in NestJS with a fail-fast env module. |
ArkEnv validates and types your environment variables when the module is imported. In a NestJS application, validating environment variables at module evaluation time gives you fail-fast runtime safety before the Nest IoC container bootstraps.
Define and validate your environment variables in src/env.ts. Export the typed env object:
import arkenv from "@arkenv/core";
export const env = arkenv({
NODE_ENV: "'development' | 'production' | 'test' = 'development'",
PORT: "number.port = 3000",
DATABASE_URL: "string",
});Import env directly across your controllers, services, and modules:
import { Injectable } from "@nestjs/common";
import { env } from "./env";
@Injectable()
export class AppService {
getDatabaseUrl(): string {
return env.DATABASE_URL;
}
}Import env at the top of src/main.ts before calling NestFactory.create(). If any required environment variables are missing or invalid, the process terminates immediately before initializing NestJS modules, providers, or database connections.
import { env } from "./env";
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(env.PORT);
}
bootstrap();Load your .env file before executing Node.js so that process.env is populated before src/env.ts evaluates. With Node.js 20.6+ and @nestjs/cli 11+, use the native --env-file flag with the Nest CLI:
nest start --env-file .envOn @nestjs/cli 10 and earlier, build the app first and run node --env-file=.env dist/main.js, or use a runner like Nub.
For production builds, ensure environment variables are injected by your deployment platform or container runner before the Node process boots.
If you prefer dependency injection over module-scoped imports, register env with a Symbol injection token using a custom provider:
import { env } from "./env";
export const ENV = Symbol("ENV");
export type Env = typeof env;
export const EnvProvider = {
provide: ENV,
useValue: env,
};Register EnvProvider in your module's providers array (and exports if used across modules), then inject ENV into services using @Inject(ENV) private readonly env: Env.
Do not pass an ArkEnv schema shape into @nestjs/config's ConfigModule.forRoot({ validationSchema }).
Starting in @nestjs/config 12, validationSchema supports Standard Schema validators, but @nestjs/config passes raw string environment variables directly to the schema without automatic type coercion. A non-coercing validator (like ArkType's number.port or Zod's z.number()) rejects "3000" with a type error instead of parsing it. In @nestjs/config 11 and earlier, validationSchema doesn't support Standard Schema validators.
Using ArkEnv directly in src/env.ts handles string coercion automatically and fails immediately before NestJS initializes.