Node.js Cheatsheet

Process and Environment

Use this Node.js reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

process Object Overview

// process is a global — no import needed
process.version;          // "v22.0.0"
process.versions;         // { node, v8, uv, zlib, ... }
process.platform;         // "linux" | "darwin" | "win32" | "freebsd" | "openbsd" | "aix"
process.arch;             // "x64" | "arm64" | "ia32" | "arm" | "loong64"
process.pid;              // process ID
process.ppid;             // parent process ID
process.title;            // process name (writable — shows in ps)
process.argv;             // ["node", "script.js", "--flag", "value"]
process.argv0;            // "node" (original argv[0])
process.execPath;         // absolute path to node binary
process.execArgv;         // node flags: ["--inspect", "--max-old-space-size=4096"]
process.cwd();            // current working directory
process.chdir("/tmp");    // change working directory
process.uptime();         // seconds since process started (float)
process.hrtime.bigint();  // nanosecond monotonic clock (BigInt)
process.memoryUsage();    // { rss, heapTotal, heapUsed, external, arrayBuffers }
process.cpuUsage();       // { user, system } in microseconds
process.cpuUsage(prev);   // delta since prev measurement
process.resourceUsage();  // extended OS resource usage (Node 12.6+)

Environment Variables

// Read
process.env.NODE_ENV;             // "production" | "development" | undefined
process.env.PORT ?? "3000";       // with fallback
process.env.DB_URL;               // all values are STRINGS

// Set (current process only, not inherited by child processes automatically)
process.env.MY_VAR = "hello";

// Delete
delete process.env.MY_VAR;

// Check existence
"MY_VAR" in process.env;         // true / false

// Enumerate all env vars
Object.entries(process.env).forEach(([k, v]) => console.log(`${k}=${v}`));

.env File Loading (Node 20.6+)

# Start with env file (no dotenv package needed)
node --env-file=.env app.js
node --env-file=.env --env-file=.env.local app.js  # layered
// .env
PORT=3000
DATABASE_URL=postgres://localhost/mydb
DEBUG=true

Values in --env-file do NOT override existing shell environment variables.

Command-Line Arguments

// process.argv = ["node", "script.js", ...user args]
const args = process.argv.slice(2);  // drop node + script path

// Simple flag parsing
const flags = Object.fromEntries(
  args
    .filter(a => a.startsWith("--"))
    .map(a => a.replace(/^--/, "").split("="))
    .map(([k, v = "true"]) => [k, v])
);
// node app.js --port=4000 --debug  →  { port: "4000", debug: "true" }

// parseArgs (Node 18.3+)
import { parseArgs } from "node:util";

const { values, positionals } = parseArgs({
  args: process.argv.slice(2),
  options: {
    port:  { type: "string",  short: "p", default: "3000" },
    debug: { type: "boolean", short: "d" },
    help:  { type: "boolean", short: "h" },
  },
  allowPositionals: true,
});
// node app.js -p 4000 --debug file.txt
// values = { port: "4000", debug: true, help: false }
// positionals = ["file.txt"]

Exit and Signals

// Exit with code
process.exit(0);    // 0 = success
process.exit(1);    // non-zero = error

// exit event fires just before exit (synchronous only)
process.on("exit", (code) => {
  // ONLY synchronous code here — no async, no I/O
  console.log("exiting with", code);
});

// beforeExit — async work before exit (not fired after process.exit())
process.on("beforeExit", async (code) => {
  await flushLogs();
});

// Signal handling
process.on("SIGINT",  () => { console.log("Ctrl+C"); gracefulShutdown(); });
process.on("SIGTERM", () => { gracefulShutdown(); });
process.on("SIGHUP",  () => { reloadConfig(); });

// Send signal to another process
process.kill(pid, "SIGTERM");
process.kill(pid, 0);  // check if process exists (no signal sent)

Common Exit Codes

CodeMeaning
0Success
1Uncaught exception
2Misuse of shell builtins
3Internal JavaScript parse error
5Fatal V8 error
9Kill signal
130Script terminated by Ctrl+C (SIGINT)

Standard I/O

// stdout / stderr — writable streams
process.stdout.write("no newline");
process.stderr.write("error message\n");

// stdin — readable stream
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => process.stdout.write(chunk));
process.stdin.on("end", () => console.log("stdin closed"));

// Check if running interactively
process.stdout.isTTY;  // true in terminal, undefined in pipe
process.stdin.isTTY;

// TTY dimensions
if (process.stdout.isTTY) {
  const { columns, rows } = process.stdout;
  console.log(`Terminal: ${columns}×${rows}`);
}

Memory Usage

const mem = process.memoryUsage();
// {
//   rss:          45678592,  // resident set size (total memory held)
//   heapTotal:    20971520,  // V8 heap allocated
//   heapUsed:     12345678,  // V8 heap in use
//   external:      567890,   // C++ objects bound to JS (Buffers)
//   arrayBuffers:  123456,   // ArrayBuffers + SharedArrayBuffers
// }

const memMB = (n) => (n / 1024 / 1024).toFixed(1) + " MB";
console.log("Heap used:", memMB(mem.heapUsed));

// Force garbage collection (only with --expose-gc flag)
global.gc && global.gc();

Performance Timing

// High-resolution timestamp
const start = process.hrtime.bigint();
doWork();
const ns = process.hrtime.bigint() - start;
console.log(`${Number(ns) / 1e6} ms`);

// performance.now() (Web-compatible, ms float)
import { performance } from "node:perf_hooks";
const t0 = performance.now();
doWork();
console.log(performance.now() - t0, "ms");

// Mark and measure
performance.mark("start");
doWork();
performance.mark("end");
performance.measure("work", "start", "end");
const [measure] = performance.getEntriesByName("work");
console.log(measure.duration, "ms");

process.nextTick vs queueMicrotask

// Both run before I/O callbacks and timers
// nextTick queue drains completely before microtasks
process.nextTick(() => console.log("nextTick"));
queueMicrotask(() => console.log("microtask"));
Promise.resolve().then(() => console.log("promise microtask"));
// Output: nextTick → microtask → promise microtask

Use queueMicrotask for user code. process.nextTick is for library internals where pre-I/O scheduling is essential (but can starve I/O if overused).