Tutorials Logic, IN info@tutorialslogic.com

Node.js Process, Environment Variables, Signals, and Shutdown

Process Lifecycle

The process boundary supplies arguments, environment, standard streams, identity, resource signals, and termination events. Validate that boundary before serving traffic and close owned resources within a bounded shutdown period.

Process Identity and Runtime Facts

The node:process API exposes argv, env, cwd, platform, architecture, version, PID, uptime, memory, CPU usage, standard streams, and process events. Use these for startup validation and diagnostics, not for hidden business behavior.

process.cwd is the directory from which the process started; it is not necessarily the module directory. Resolve application files from a deliberate base such as import.meta.url, and reserve cwd for user-selected workspace semantics.

  • Log the supported Node major at startup.
  • Do not confuse cwd with module location.
  • Expose only safe runtime facts in diagnostics.

Command-Line Arguments

process.argv contains the Node executable, entry script, and user arguments. Parse options with util.parseArgs or a maintained parser, reject unknown flags in strict tools, and validate semantic values after syntax parsing.

Use exit code 0 for success and nonzero values for failure. Print normal command output to stdout and diagnostics to stderr so automation can separate them. Avoid process.exit while output may still be buffered; set process.exitCode and let clean work finish.

Parse a Required Port Option

Parse a Required Port Option
import { parseArgs } from 'node:util';

const { values } = parseArgs({
  options: { port: { type: 'string', short: 'p' } },
  strict: true
});
const port = Number(values.port ?? 3000);
if (!Number.isInteger(port) || port < 1 || port > 65535) {
  throw new Error('port must be an integer from 1 to 65535');
}
console.log(port);

Argument parsing establishes syntax; application validation establishes the valid port domain.

Environment and Built-In DotEnv

process.env values are strings or absent. Parse booleans, integers, URLs, durations, and lists deliberately; the text false is truthy in JavaScript. Validate required configuration once during startup and expose a typed, immutable configuration object to the rest of the application.

Node 24 has stable .env support through --env-file, --env-file-if-exists, process.loadEnvFile, and util.parseEnv. Define precedence between deployment variables and files. Keep secret files out of version control and never dump the full environment into logs or error pages.

Validate Environment at Startup

Validate Environment at Startup
const required = ['DATABASE_URL', 'APP_ORIGIN'];
for (const name of required) {
  if (!process.env[name]) throw new Error(`Missing environment variable: ${name}`);
}

const config = Object.freeze({
  databaseUrl: new URL(process.env.DATABASE_URL),
  origin: new URL(process.env.APP_ORIGIN).origin
});

The application fails before accepting traffic and converts text into typed values once.

Standard Input, Output, and Error

process.stdin is readable; stdout and stderr are writable. Their blocking behavior can differ by destination and platform, so high-volume production logging needs backpressure-aware structured output. Do not write protocol responses to stdout when the process uses stdout for machine communication.

Handle EPIPE when output is piped to a consumer that exits early. Avoid secrets and oversized objects in diagnostics, and include stable event names and correlation IDs rather than composing unsearchable prose.

Signals and Graceful Shutdown

Deployment systems commonly send SIGTERM; interactive terminals commonly send SIGINT. On the first signal, mark the service unready, stop accepting new connections, allow in-flight work a deadline, close database pools and queues, then set a successful exit code when shutdown completes.

Signal handlers replace default termination behavior, so a handler must actually complete the process lifecycle. On a second signal or expired deadline, record the forced exit and terminate. Signal behavior differs on Windows; test on the production platform or container environment.

Fatal Process Errors

uncaughtException and unhandledRejection indicate work escaped its intended boundary. Record minimal synchronous fatal context and begin shutdown; continuing can preserve corrupted assumptions or partially completed work. A supervisor should restart the process.

Do not perform arbitrary asynchronous recovery inside the exit event because the event loop is ending. beforeExit is not a general shutdown signal and is not emitted for every termination path. Durable work needs transactions, queues, or idempotency rather than faith in a final callback.

Startup and Shutdown Verification

Test missing and malformed configuration, unavailable dependencies, read-only file systems, occupied ports, SIGTERM during idle and active requests, a second signal, and shutdown timeout. Readiness must stay false until dependencies required for traffic are ready.

Track startup duration, configuration schema version, shutdown reason, active request count, and close failures. Never label a process healthy merely because it exists; health, readiness, and liveness answer different operational questions.

Before you move on

Process Lifecycle Check

4 checks
  • I parse environment strings into typed configuration.
  • I use meaningful stdout, stderr, and exit-code contracts.
  • I handle SIGTERM with bounded graceful shutdown.
  • I treat fatal uncaught errors as restart conditions.

Node JS Questions Learners Ask

No. Values are strings or undefined, so numbers, booleans, URLs, and lists need explicit parsing and validation.

It terminates immediately and may truncate buffered output or cleanup. Set exitCode, close resources, and allow the loop to finish within a deadline.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.