Script Valley
Node.js: The Complete Runtime
Authentication and SecurityLesson 5.5

Environment configuration and secrets management in Node.js

dotenv, process.env, config validation with Zod, .env.example, never committing secrets, NODE_ENV, 12-factor app

Config as Environment Variables

The 12-factor app principle: all configuration lives in the environment, not in code. This includes database URLs, JWT secrets, API keys, and port numbers.

npm install dotenv zod
const { z } = require('zod');
require('dotenv').config();

const ConfigSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']),
  PORT: z.coerce.number().default(3000),
  DATABASE_URL: z.string().url(),
  JWT_SECRET: z.string().min(32),
  JWT_EXPIRES_IN: z.string().default('15m')
});

const result = ConfigSchema.safeParse(process.env);
if (!result.success) {
  console.error('Invalid config:', result.error.flatten().fieldErrors);
  process.exit(1);
}

module.exports = result.data;
const config = require('./config');
app.listen(config.PORT);

.env.example

Always commit a .env.example with placeholder values — it documents required variables without exposing secrets. Never commit the real .env. In production, inject secrets via your hosting platform's environment variables, not files.