The process module provides information about and control over the current Node.js process. Here's how to use it.
Environment Variables#
1// Access environment variables
2const nodeEnv = process.env.NODE_ENV;
3const port = process.env.PORT || 3000;
4const apiKey = process.env.API_KEY;
5
6// Check environment
7const isDev = process.env.NODE_ENV === 'development';
8const isProd = process.env.NODE_ENV === 'production';
9
10// Set environment variable (runtime only)
11process.env.MY_VAR = 'value';
12
13// All environment variables
14console.log(process.env);
15
16// Common patterns
17const config = {
18 port: parseInt(process.env.PORT, 10) || 3000,
19 dbUrl: process.env.DATABASE_URL,
20 debug: process.env.DEBUG === 'true',
21 logLevel: process.env.LOG_LEVEL || 'info',
22};Command Line Arguments#
1// Raw arguments
2console.log(process.argv);
3// ['/path/to/node', '/path/to/script.js', 'arg1', 'arg2']
4
5// Skip node and script path
6const args = process.argv.slice(2);
7
8// Simple argument parsing
9const flags = {};
10const positional = [];
11
12for (const arg of args) {
13 if (arg.startsWith('--')) {
14 const [key, value] = arg.slice(2).split('=');
15 flags[key] = value ?? true;
16 } else if (arg.startsWith('-')) {
17 flags[arg.slice(1)] = true;
18 } else {
19 positional.push(arg);
20 }
21}
22
23// Usage: node script.js --verbose --port=3000 file.txt
24// flags: { verbose: true, port: '3000' }
25// positional: ['file.txt']Process Information#
1// Process ID
2console.log('PID:', process.pid);
3console.log('Parent PID:', process.ppid);
4
5// Node.js version
6console.log('Node Version:', process.version);
7console.log('V8 Version:', process.versions.v8);
8
9// Platform info
10console.log('Platform:', process.platform); // 'darwin', 'linux', 'win32'
11console.log('Architecture:', process.arch); // 'x64', 'arm64'
12
13// Current working directory
14console.log('CWD:', process.cwd());
15
16// Change directory
17process.chdir('/path/to/dir');
18
19// Script location
20console.log('Script:', process.argv[1]);
21console.log('Execution path:', process.execPath);Memory Usage#
1// Memory usage in bytes
2const memory = process.memoryUsage();
3
4console.log({
5 rss: `${Math.round(memory.rss / 1024 / 1024)} MB`, // Resident Set Size
6 heapTotal: `${Math.round(memory.heapTotal / 1024 / 1024)} MB`,
7 heapUsed: `${Math.round(memory.heapUsed / 1024 / 1024)} MB`,
8 external: `${Math.round(memory.external / 1024 / 1024)} MB`,
9});
10
11// Format helper
12function formatMemory() {
13 const mem = process.memoryUsage();
14 const format = (bytes) => `${(bytes / 1024 / 1024).toFixed(2)} MB`;
15
16 return {
17 rss: format(mem.rss),
18 heapTotal: format(mem.heapTotal),
19 heapUsed: format(mem.heapUsed),
20 };
21}
22
23// Memory monitoring
24setInterval(() => {
25 console.log('Memory:', formatMemory());
26}, 5000);Process Exit#
1// Exit with success
2process.exit(0);
3
4// Exit with error
5process.exit(1);
6
7// Exit code without exiting
8process.exitCode = 1;
9
10// Clean exit
11function gracefulShutdown() {
12 console.log('Shutting down...');
13
14 server.close(() => {
15 db.disconnect(() => {
16 process.exit(0);
17 });
18 });
19
20 // Force exit after timeout
21 setTimeout(() => {
22 process.exit(1);
23 }, 10000);
24}
25
26// Exit event (synchronous only)
27process.on('exit', (code) => {
28 console.log('Exit code:', code);
29 // Cannot do async work here!
30});
31
32// Before exit (can do async)
33process.on('beforeExit', async (code) => {
34 await cleanup();
35 console.log('Cleaned up');
36});Signal Handling#
1// SIGINT (Ctrl+C)
2process.on('SIGINT', () => {
3 console.log('Received SIGINT');
4 gracefulShutdown();
5});
6
7// SIGTERM (kill command)
8process.on('SIGTERM', () => {
9 console.log('Received SIGTERM');
10 gracefulShutdown();
11});
12
13// SIGHUP (terminal closed)
14process.on('SIGHUP', () => {
15 console.log('Received SIGHUP');
16 reloadConfig();
17});
18
19// Windows doesn't support all signals
20if (process.platform !== 'win32') {
21 process.on('SIGUSR1', () => {
22 console.log('Received SIGUSR1');
23 });
24}
25
26// Remove signal handler
27function handler() { /* ... */ }
28process.on('SIGINT', handler);
29process.off('SIGINT', handler);Error Handling#
1// Uncaught exceptions
2process.on('uncaughtException', (error, origin) => {
3 console.error('Uncaught Exception:', error);
4 console.error('Origin:', origin);
5
6 // Log error
7 fs.writeSync(
8 process.stderr.fd,
9 `Uncaught Exception: ${error}\n`
10 );
11
12 process.exit(1);
13});
14
15// Unhandled promise rejections
16process.on('unhandledRejection', (reason, promise) => {
17 console.error('Unhandled Rejection:', reason);
18
19 // In Node.js 15+, unhandled rejections crash by default
20});
21
22// Rejection handled later
23process.on('rejectionHandled', (promise) => {
24 console.log('Rejection handled');
25});
26
27// Warning events
28process.on('warning', (warning) => {
29 console.warn('Warning:', warning.name, warning.message);
30});
31
32// Emit custom warning
33process.emitWarning('Something deprecated', 'DeprecationWarning');Standard I/O#
1// Standard streams
2process.stdin // Readable stream
3process.stdout // Writable stream
4process.stderr // Writable stream
5
6// Write to stdout
7process.stdout.write('Hello\n');
8
9// Write to stderr
10process.stderr.write('Error message\n');
11
12// Read from stdin
13process.stdin.setEncoding('utf8');
14process.stdin.on('data', (data) => {
15 console.log('Input:', data.trim());
16});
17
18// Pipe stdin to stdout
19process.stdin.pipe(process.stdout);
20
21// Check if TTY (terminal)
22if (process.stdout.isTTY) {
23 console.log('Running in terminal');
24 console.log('Columns:', process.stdout.columns);
25 console.log('Rows:', process.stdout.rows);
26}Timing Functions#
1// High-resolution time
2const start = process.hrtime.bigint();
3// ... do work
4const end = process.hrtime.bigint();
5console.log(`Took ${end - start} nanoseconds`);
6
7// Legacy hrtime
8const [seconds, nanoseconds] = process.hrtime();
9
10// Diff from previous
11const startTime = process.hrtime();
12// ... do work
13const [secs, nanos] = process.hrtime(startTime);
14console.log(`Took ${secs}s ${nanos}ns`);
15
16// CPU usage
17const startUsage = process.cpuUsage();
18// ... do work
19const diff = process.cpuUsage(startUsage);
20console.log('CPU:', diff); // { user, system } in microseconds
21
22// Process uptime
23console.log('Uptime:', process.uptime(), 'seconds');Next Tick#
1// Schedule callback before I/O
2process.nextTick(() => {
3 console.log('Next tick');
4});
5
6console.log('Current tick');
7
8// Output:
9// Current tick
10// Next tick
11
12// Compare with setImmediate
13process.nextTick(() => console.log('nextTick'));
14setImmediate(() => console.log('setImmediate'));
15console.log('sync');
16
17// Output:
18// sync
19// nextTick
20// setImmediate
21
22// Use case: Emit events after constructor
23class MyEmitter extends EventEmitter {
24 constructor() {
25 super();
26 process.nextTick(() => {
27 this.emit('ready');
28 });
29 }
30}
31
32const emitter = new MyEmitter();
33emitter.on('ready', () => console.log('Ready!'));Resource Limits#
1// Resource usage (Unix only)
2const usage = process.resourceUsage();
3console.log(usage);
4
5// Limits
6process.setUncaughtExceptionCaptureCallback((err) => {
7 console.error('Captured:', err);
8});
9
10// Max listeners warning threshold
11process.setMaxListeners(20);
12
13// Environment size
14process.env.LARGE_VAR = 'x'.repeat(1000000);
15// Be careful with large env varsDebugging#
1// Debug port
2console.log('Debug port:', process.debugPort);
3
4// Active handles and requests
5console.log('Active handles:', process._getActiveHandles().length);
6console.log('Active requests:', process._getActiveRequests().length);
7
8// Force garbage collection (requires --expose-gc flag)
9if (global.gc) {
10 global.gc();
11}
12
13// Report (requires Node.js 12+)
14const report = process.report;
15if (report) {
16 console.log(report.getReport());
17}Best Practices#
Environment:
✓ Validate required env vars at startup
✓ Use defaults for optional vars
✓ Don't store secrets in code
✓ Parse/validate env var types
Signals:
✓ Handle SIGTERM for graceful shutdown
✓ Handle SIGINT for dev convenience
✓ Set exit codes appropriately
✓ Clean up resources on exit
Errors:
✓ Log uncaught exceptions
✓ Handle unhandled rejections
✓ Exit after fatal errors
✓ Monitor warnings
Avoid:
✗ Swallowing uncaught exceptions
✗ Ignoring unhandled rejections
✗ Synchronous work in exit handlers
✗ Modifying process.env in production
Conclusion#
The process module is essential for Node.js applications. Use it for environment configuration, command-line argument parsing, graceful shutdown handling, and error management. Always handle SIGTERM and SIGINT for proper shutdown, log uncaught errors, and set appropriate exit codes. The process module provides valuable debugging information about memory usage, timing, and system resources.