process / env
The process global is Node’s window into the running runtime: env vars, argv, stdio, lifecycle signals, exit codes, performance metrics.
env, argv, signals, exit, uncaught
EXAMPLE
// 1) Environment variables
const NODE_ENV = process.env.NODE_ENV ?? 'development';
const PORT = parseInt(process.env.PORT ?? '3000', 10);
const DB_URL = process.env.DB_URL;
if (!DB_URL) {
console.error('DB_URL not set');
process.exit(1);
}
// dotenv pattern — load .env in dev
import 'dotenv/config'; // npm i dotenv
// 2) Command-line arguments
console.log(process.argv);
// ['/path/to/node', '/path/to/script.js', 'arg1', 'arg2']
const [, , ...args] = process.argv;
const flag = args.includes('--verbose');
// For real CLI parsing: yargs, commander, minimist
// 3) Working directory + paths
process.cwd(); // /home/me/project
process.chdir('/tmp');
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
// 4) Platform + arch
process.platform; // 'linux' | 'darwin' | 'win32'
process.arch; // 'x64' | 'arm64'
process.version; // 'v20.10.0'
process.versions; // { node, v8, openssl, ... }
if (process.platform === 'win32') { /* Windows-specific */ }
// 5) Stdio
process.stdout.write('hello\n'); // bypass console.log
process.stderr.write('error\n');
// Read from stdin
process.stdin.setEncoding('utf8');
process.stdin.on('data', (chunk) => {
console.log('got:', chunk);
});
// Or async iterator
for await (const chunk of process.stdin) {
console.log(chunk.toString());
}
// 6) Exit codes
process.exit(0); // success
process.exit(1); // generic error
process.exit(2); // misuse of shell builtins
process.exit(130); // 128 + SIGINT
// Don't exit before pending I/O drains — set exitCode and return
process.exitCode = 1;
return;
// 7) Signals — graceful shutdown
import http from 'node:http';
const server = http.createServer(handler);
server.listen(3000);
function shutdown(signal) {
console.log(`${signal} received, draining`);
server.close((err) => {
if (err) return process.exit(1);
db.close().then(() => process.exit(0));
});
// Force kill if hung
setTimeout(() => process.exit(1), 10_000).unref();
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
// 8) Uncaught exception / unhandled rejection
process.on('uncaughtException', (err) => {
log.fatal({ err }, 'uncaught — exiting');
process.exit(1); // safest to exit
});
process.on('unhandledRejection', (reason) => {
log.fatal({ reason }, 'unhandled promise rejection — exiting');
process.exit(1);
});
// 9) Memory + CPU info
process.memoryUsage();
// { rss: 75939840, heapTotal: 21618688, heapUsed: 16519856, external: 1854784 }
process.cpuUsage();
// { user: 12345, system: 6789 } in microseconds
process.uptime(); // seconds since process start
process.hrtime.bigint(); // high-resolution time
// 10) PID + parent
process.pid;
process.ppid;
process.title = 'myapp'; // visible in ps, top
// 11) Resource limits
process.getuid(); // *nix only
process.getgid();
process.setuid(1000); // drop privileges (needs root)
process.setgid(1000);
// 12) Next tick + microtasks
process.nextTick(() => console.log('next tick — before promises'));
queueMicrotask(() => console.log('microtask — after nextTick'));
// 13) Environment-specific patterns
// Conditional behaviour
if (process.env.NODE_ENV === 'production') {
// Strict error handling
} else {
// Pretty error messages, sourcemaps
}
// CI detection
if (process.env.CI === 'true' || process.env.CI === '1') {
// No interactive prompts; no colors
}
// 14) Validate env at startup — zod/envalid
import { z } from 'zod';
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'test']),
PORT: z.coerce.number().int().positive().default(3000),
DB_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
});
const env = envSchema.parse(process.env);
// env is fully typed; missing/invalid values throw at startup
// 15) Common bugs
// • Forgetting process.exit() in CLI scripts that have open handles → hangs
// • Reading process.env.X without default → cryptic errors
// • Using process.exit(1) before logs flush → losing the error
// • Trapping SIGTERM but not draining connections → 502s during deploy
// • console.log in production logs → use a structured logger (pino, winston)
Why it matters
Validate process.env with Zod or envalid at startup — missing or wrong-typed vars become a clear error at boot, not a 3am page. Handle SIGTERM gracefully or every deploy generates 502s.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
console.log(process.argv);
console.log(process.env.NODE_ENV);
process.on('SIGTERM', () => server.close());
Try it Yourself »
Discussion
Loading…