iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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…