Global Objects & Built-in Utilities

📖 Concept

Node.js provides several global objects that are available everywhere without requiring an import. Understanding these is essential for writing idiomatic Node.js code.

Key globals in Node.js:

Global Purpose Browser Equivalent
global The global namespace object window
globalThis Universal global (works in Node + browser) globalThis
process Current process info, env vars, stdin/stdout (none)
console Logging and debugging console
Buffer Binary data handling ArrayBuffer
__filename Current file's absolute path (CJS only) (none)
__dirname Current directory's absolute path (CJS only) (none)
setTimeout / setInterval Timer scheduling Same API
setImmediate Run after current I/O (none)
URL / URLSearchParams URL parsing Same API
TextEncoder / TextDecoder String ↔ binary encoding Same API
structuredClone Deep clone objects Same API
fetch HTTP requests (Node 18+) Same API
AbortController Cancel async operations Same API
crypto Web Crypto API (Node 19+) Same API

__filename and __dirname in ESM: In ES Modules, __filename and __dirname don't exist. Use:

import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

The process object — your Swiss Army knife: process is the most important global in Node.js. It provides:

  • process.env — Environment variables (config, secrets)
  • process.argv — Command-line arguments
  • process.exit(code) — Exit with status code (0 = success, 1 = error)
  • process.cwd() — Current working directory
  • process.stdin / process.stdout — Standard I/O streams
  • process.memoryUsage() — Heap and RSS memory stats
  • process.hrtime.bigint() — High-resolution timing (nanosecond precision)
  • process.on('uncaughtException') — Last resort error handler

The Buffer class: Buffers are Node.js's way of handling raw binary data — essential for file I/O, network protocols, and cryptography. Unlike strings, Buffers have a fixed size and store raw bytes.

🏠 Real-world analogy: Globals are like the utilities in your apartment — electricity, water, and gas are always available without ordering them. But just because they're available doesn't mean you should leave all the taps running (global variable pollution).

💻 Code Example

codeTap to expand ⛶
1// Node.js Global Objects — practical usage
2
3// 1. process.env — Configuration management
4// ✅ GOOD: Use environment variables for config
5const config = {
6 port: parseInt(process.env.PORT || "3000"),
7 dbUrl: process.env.DATABASE_URL || "mongodb://localhost:27017/myapp",
8 nodeEnv: process.env.NODE_ENV || "development",
9 isProduction: process.env.NODE_ENV === "production",
10 logLevel: process.env.LOG_LEVEL || "info",
11};
12console.log("Config:", config);
13
14// 2. process.argv — CLI argument parsing
15// Run: node script.js --name "John" --verbose
16function parseArgs(argv) {
17 const args = {};
18 for (let i = 2; i < argv.length; i++) {
19 if (argv[i].startsWith("--")) {
20 const key = argv[i].slice(2);
21 const value = argv[i + 1] && !argv[i + 1].startsWith("--")
22 ? argv[++i]
23 : true;
24 args[key] = value;
25 }
26 }
27 return args;
28}
29console.log("Parsed args:", parseArgs(process.argv));
30
31// 3. Buffer — Binary data handling
32// Create buffers
33const buf1 = Buffer.from("Hello, Node.js!", "utf-8");
34const buf2 = Buffer.alloc(16); // 16 zero-filled bytes
35const buf3 = Buffer.allocUnsafe(16); // 16 uninitialized bytes (faster)
36
37console.log("\n--- Buffer ---");
38console.log("String to Buffer:", buf1);
39console.log("Buffer to String:", buf1.toString("utf-8"));
40console.log("Buffer to Hex:", buf1.toString("hex"));
41console.log("Buffer to Base64:", buf1.toString("base64"));
42console.log("Buffer length:", buf1.length, "bytes");
43
44// Compare buffers
45const a = Buffer.from("abc");
46const b = Buffer.from("abc");
47const c = Buffer.from("abd");
48console.log("a === b:", a === b); // false (different references)
49console.log("a.equals(b):", a.equals(b)); // true (same content)
50console.log("a.compare(c):", a.compare(c)); // -1 (a < c)
51
52// 4. High-resolution timing
53const start = process.hrtime.bigint();
54// Simulate work
55let sum = 0;
56for (let i = 0; i < 1_000_000; i++) sum += i;
57const end = process.hrtime.bigint();
58console.log(`\nLoop took ${(end - start) / 1_000_000n}ms`);
59
60// 5. console methods beyond console.log
61console.log("\n--- Console methods ---");
62console.table([
63 { method: "log", use: "General output" },
64 { method: "error", use: "Error output (stderr)" },
65 { method: "warn", use: "Warning output (stderr)" },
66 { method: "time/timeEnd", use: "Measure execution time" },
67 { method: "table", use: "Display tabular data" },
68 { method: "dir", use: "Object inspection with depth" },
69]);
70
71console.time("array-creation");
72const bigArray = Array.from({ length: 100000 }, (_, i) => i);
73console.timeEnd("array-creation");
74
75// 6. structuredClone — Deep cloning (Node 17+)
76const original = {
77 name: "Alice",
78 nested: { scores: [1, 2, 3] },
79 date: new Date(),
80};
81const cloned = structuredClone(original);
82cloned.nested.scores.push(4);
83console.log("\nOriginal scores:", original.nested.scores); // [1, 2, 3]
84console.log("Cloned scores:", cloned.nested.scores); // [1, 2, 3, 4]
85
86// 7. AbortController — Cancel async operations
87async function fetchWithTimeout(url, timeoutMs) {
88 const controller = new AbortController();
89 const timeout = setTimeout(() => controller.abort(), timeoutMs);
90
91 try {
92 const response = await fetch(url, { signal: controller.signal });
93 return await response.json();
94 } catch (err) {
95 if (err.name === "AbortError") {
96 console.log("Request timed out!");
97 }
98 throw err;
99 } finally {
100 clearTimeout(timeout);
101 }
102}

🏋️ Practice Exercise

Exercises:

  1. Write a CLI tool that reads process.env and prints all variables matching a given prefix (e.g., AWS_)
  2. Implement a simple argument parser that supports --flag value, -f, and --boolean-flag patterns
  3. Convert a string to Buffer, then to Base64, then back to string — verify it round-trips correctly
  4. Use process.hrtime.bigint() to write a benchmarking utility that runs a function N times and reports min/max/avg
  5. Create a script that monitors process.memoryUsage() every second and logs when heap usage exceeds 80%
  6. Write a structuredClone vs JSON.parse(JSON.stringify()) benchmark — which is faster for deep objects?

⚠️ Common Mistakes

  • Polluting the global object by attaching properties to it — this creates hard-to-debug shared state and naming conflicts across modules

  • Using __dirname and __filename in ES modules — they only exist in CommonJS; use import.meta.url with fileURLToPath instead

  • Calling process.exit() in a server without graceful shutdown — this kills active connections; use signals (SIGTERM/SIGINT) instead

  • Using Buffer.allocUnsafe() without filling it — the buffer contains old memory data which could leak sensitive information

  • Not using process.env for configuration — hardcoding secrets, ports, or database URLs makes deployment impossible

💼 Interview Questions

🎤 Mock Interview

Mock interview is powered by AI for Global Objects & Built-in Utilities. Login to unlock this feature.