Working with Environment and Configuration

1. Loading .env Files

Example: Built-in loader v20.6+

node --env-file=.env app.js
node --env-file-if-exists=.env.local --env-file=.env app.js
ToolUse
--env-fileBuilt-in, no deps
dotenvLibrary, broader features
dotenvxEncrypted env files

2. Accessing process.env Variables

PatternNotes
const port = +process.env.PORTCoerce string → number
process.env.DEBUG === "true"Coerce to bool explicitly
delete process.env.SECRETRemove from env

3. Setting Default Values (|| operator, ?? nullish coalescing)

OperatorTreats As Missing
||Any falsy ("", 0, false, null, undefined)
??Only null/undefined

Example

const port = process.env.PORT ?? 3000;       // keeps "0" if set
const flag = process.env.FLAG === "true";     // explicit bool

4. Using NODE_ENV for Environment Detection

ValueConvention
developmentVerbose logs, hot reload
productionOptimized, minimal logging
testAutomated tests

5. Managing Multiple Environments

FileLoaded When
.envAlways (committed defaults / shared)
.env.localLocal overrides (gitignored)
.env.<env>Per-environment
.env.<env>.localPer-env local override

6. Using config Libraries

LibraryStrength
node-configHierarchical JSON/JS config
convictSchema + validation
env-varTyped env parsing
zod / valibotSchema-validate process.env

7. Using Environment-Specific Configs

Example: Switch by NODE_ENV

const env = process.env.NODE_ENV ?? "development";
const config = (await import(`./config/${env}.js`)).default;

8. Validating Environment Variables

Example: Zod schema

import { z } from "zod";
const env = z.object({
  PORT: z.coerce.number().int().positive(),
  DATABASE_URL: z.string().url(),
  NODE_ENV: z.enum(["development","production","test"])
}).parse(process.env);
PracticeWhy
Fail fast at startupAvoid runtime crashes
Coerce typesenv vars are always strings

9. Using cross-env for Cross-Platform

Example

{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack"
  }
}
ProblemSolution
Windows can't do FOO=bar cmdcross-env normalizes syntax

10. Securing Sensitive Data

PracticeDetail
Never commit secretsUse .gitignore for .env*
Use a secrets managerAWS Secrets Manager, HashiCorp Vault, Doppler
Rotate regularlyAutomate
Limit scopePer-service credentials
Audit dependenciesnpm audit, Snyk