Global Objects & the process Object
5 questions found
What is the process object in Node.js, and what are some of the most commonly used properties and methods on it?
Beginner
process is a global object providing information about, and control over, the currently running Node.js process -- commonly used members include process.env (environment variables), process.argv (command-line arguments), process.exit() (terminate the process), process.cwd() (current working directory), process.platform (the OS), and process.on() for listening to process-level events like 'exit', 'uncaughtException', or signals like SIGTERM.
console.log(process.env.NODE_ENV);
console.log(process.argv); // ['node', '/path/to/script.js', 'arg1', 'arg2']
console.log(process.cwd());
console.log(process.platform); // 'linux', 'darwin', 'win32'
console.log(process.version); // e.g. 'v20.11.0'
Real-world example
A CLI tool reads its configuration from process.env, accepts additional arguments via process.argv, and uses process.platform to apply OS-specific path handling logic, all without needing any external dependency for these fundamental process-level capabilities.
Common follow-ups: What's the difference between process.argv[0], process.argv[1], and the arguments that follow?;Why is process considered a global object available without needing to require() it, unlike most other Node.js functionality?
Environment Variables & Configuration;CLI Tools & Scripting with Node.js
What is the difference between __dirname/__filename in CommonJS and their equivalents in ES Modules?
Intermediate
In CommonJS, __dirname and __filename are automatically available in every module, providing the absolute path to the current file's directory and the file itself. ES Modules don't have these globals at all (since ESM was designed to be more portable, including for non-file-based module sources); the equivalent in ESM is derived from import.meta.url, typically converted to a filesystem path using the node:url module's fileURLToPath() function.
// CommonJS
console.log(__dirname); // /path/to/current/directory
console.log(__filename); // /path/to/current/directory/file.js
// ES Modules equivalent
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Real-world example
A team migrating a CommonJS codebase to ES Modules encounters build failures everywhere __dirname was used to resolve relative file paths, requiring them to add the fileURLToPath(import.meta.url) pattern at the top of each affected file as part of the migration.
Common follow-ups: Why did the designers of ES Modules choose not to include __dirname and __filename as built-in globals?;How does this same path-resolution need get handled differently again when the code is bundled for a browser environment?
Modules (CommonJS/ESM);Path & OS Modules
What is process.memoryUsage(), and how would you use it to monitor a Node.js application's memory consumption?
Intermediate
process.memoryUsage() returns an object describing the current process's memory usage across several categories: rss (Resident Set Size, total memory allocated for the process including all C++ and JS objects), heapTotal and heapUsed (V8's JavaScript heap, allocated versus actually used), external (memory used by C++ objects bound to JavaScript objects, like Buffers), and arrayBuffers -- useful for building custom memory monitoring, alerting, or diagnosing suspected leaks by tracking these values over time.
setInterval(() => {
const mem = process.memoryUsage();
console.log({
rss: `${(mem.rss / 1024 / 1024).toFixed(1)} MB`,
heapUsed: `${(mem.heapUsed / 1024 / 1024).toFixed(1)} MB`,
});
}, 30000);
Real-world example
An operations team adds a periodic process.memoryUsage() log line to their application, feeding heapUsed into their monitoring dashboard, which lets them spot a slow, steady upward trend over several hours -- a telltale sign of a memory leak -- well before it would otherwise cause an out-of-memory crash.
Common follow-ups: Why can rss be significantly larger than heapUsed, and what does that difference represent?;How would you set up an automated alert to fire when heapUsed exceeds a certain threshold or shows a sustained upward trend?
Memory Management & Garbage Collection;Logging & Monitoring
How do you correctly handle OS signals like SIGTERM and SIGINT in a Node.js application to implement graceful shutdown?
Advanced
process.on('SIGTERM', ...) and process.on('SIGINT', ...) let an application intercept termination signals sent by an orchestrator (SIGTERM, typically during a deployment or scale-down) or a user pressing Ctrl+C in a terminal (SIGINT), giving the application a chance to stop accepting new work, finish in-flight requests, close database connections cleanly, and only then actually exit -- without a handler, Node.js's default behavior for these signals is to terminate the process immediately, potentially interrupting in-progress work abruptly.
let server;
function gracefulShutdown(signal) {
console.log(`Received ${signal}, shutting down gracefully...`);
server.close(() => {
db.close();
process.exit(0);
});
setTimeout(() => process.exit(1), 10000); // force exit if graceful shutdown hangs
}
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
Real-world example
A Kubernetes-deployed API implements a SIGTERM handler that stops accepting new HTTP connections and waits for in-flight requests to complete (with a hard timeout fallback), ensuring rolling deployments never abruptly cut off a customer's in-progress checkout request mid-transaction.
Common follow-ups: Why is a hard timeout fallback (forcing exit after N seconds) an important safety net alongside graceful shutdown logic?;How much time does Kubernetes give a pod between sending SIGTERM and forcibly sending SIGKILL by default, and how does that affect your shutdown timeout budget?
Deployment & Process Managers (PM2);Background Jobs & Queues
What is the global Buffer class, and how does it relate to the process object's broader role in giving access to system-level capabilities?
Intermediate
Buffer is a global class (no require() needed) for working with raw binary data directly, predating and complementing JavaScript's later-added standard TypedArray classes -- like process, it's part of Node.js's set of globals that expose lower-level, system-oriented capabilities not present in browser JavaScript, reflecting Node's original design goal of giving JavaScript direct access to I/O and binary data manipulation for building servers and system tools.
const buf = Buffer.from('Hello', 'utf-8');
console.log(buf); // <Buffer 48 65 6c 6c 6f>
console.log(buf.toString('utf-8')); // 'Hello'
console.log(buf.length); // 5
const buf2 = Buffer.alloc(10); // allocates 10 zeroed bytes
Real-world example
A binary file-parsing utility uses Buffer directly to read and manipulate raw bytes from a custom binary file format, relying on Buffer's specific methods for reading integers at specific byte offsets (readUInt32BE, etc.) that plain JavaScript strings or arrays don't provide.
Common follow-ups: Why does Node.js provide both Buffer and standard TypedArrays, and how do they relate to each other under the hood?;What's the security risk of using the older Buffer() constructor directly (now deprecated) versus Buffer.alloc() or Buffer.from()?
ArrayBuffer
TypedArrays & Binary Data;Streams & Buffers