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
| Tool | Use |
|---|---|
--env-file | Built-in, no deps |
dotenv | Library, broader features |
dotenvx | Encrypted env files |
2. Accessing process.env Variables
| Pattern | Notes |
|---|---|
const port = +process.env.PORT | Coerce string → number |
process.env.DEBUG === "true" | Coerce to bool explicitly |
delete process.env.SECRET | Remove from env |
3. Setting Default Values (|| operator, ?? nullish coalescing)
| Operator | Treats 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
| Value | Convention |
|---|---|
development | Verbose logs, hot reload |
production | Optimized, minimal logging |
test | Automated tests |
5. Managing Multiple Environments
| File | Loaded When |
|---|---|
.env | Always (committed defaults / shared) |
.env.local | Local overrides (gitignored) |
.env.<env> | Per-environment |
.env.<env>.local | Per-env local override |
6. Using config Libraries
| Library | Strength |
|---|---|
| node-config | Hierarchical JSON/JS config |
| convict | Schema + validation |
| env-var | Typed env parsing |
| zod / valibot | Schema-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);
| Practice | Why |
|---|---|
| Fail fast at startup | Avoid runtime crashes |
| Coerce types | env vars are always strings |
9. Using cross-env for Cross-Platform
| Problem | Solution |
|---|---|
Windows can't do FOO=bar cmd | cross-env normalizes syntax |
10. Securing Sensitive Data
| Practice | Detail |
|---|---|
| Never commit secrets | Use .gitignore for .env* |
| Use a secrets manager | AWS Secrets Manager, HashiCorp Vault, Doppler |
| Rotate regularly | Automate |
| Limit scope | Per-service credentials |
| Audit dependencies | npm audit, Snyk |