Skip to content
JavaScript Basics: Validate Environment Variables in Node.js

JavaScript Basics: Validate Environment Variables in Node.js

October 14, 2026

Environment variables let you configure a program when you launch it. A setting that looks like a number or boolean still arrives as text, so checking it early prevents confusing failures later. This tutorial reads two settings, validates them, and prints the resulting configuration.

Prepare a scratch directory

You need Linux, Bash, the env, mktemp, rm, and rmdir utilities, a text editor, and Node.js on your PATH. These examples were tested with Node.js v24.19.0. They need no npm packages, package manifest, or network access. The program does not start a server or open a port.

Run these commands and keep this Bash session open:

node --version
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

The tested runtime prints:

v24.19.0

Save the following files with your editor inside this directory. The example variables are DEMO_PORT and DEMO_VERBOSE. Each run sets or removes them for that child process only, preserving any existing settings in your Bash session.

Convert text into checked settings

Save as read-environment-config.mjs:

function readConfiguration(env) {
  const portText = env.DEMO_PORT ?? "3000";
  if (portText.length === 0 || /[^0-9]/u.test(portText)) {
    throw new Error("DEMO_PORT must contain only decimal digits.");
  }

  const port = Number(portText);
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
    throw new Error("DEMO_PORT must be between 1 and 65535.");
  }

  const verboseText = env.DEMO_VERBOSE ?? "false";
  if (verboseText !== "true" && verboseText !== "false") {
    throw new Error("DEMO_VERBOSE must be true or false.");
  }

  return Object.freeze({
    port,
    verbose: verboseText === "true",
  });
}

try {
  const config = readConfiguration(process.env);
  console.log(`Port: ${config.port}`);
  console.log(`Verbose: ${config.verbose}`);
} catch (error) {
  console.error(`Configuration error: ${error.message}`);
  process.exitCode = 2;
}

The Node environment-variable guide explains why values arrive as strings. Missing settings produce undefined, so ?? supplies defaults. An explicitly empty value stays empty and fails validation instead of silently becoming a default.

The regular expression finds any character that is not an ASCII digit. Together with the empty-string check, it rejects whitespace, signs, fractions, and suffixes. Number then converts the whole string, and the range check accepts ports from 1 through 65535. This is the example’s configuration rule; no attempt is made to bind that port. Leading zeros are accepted and disappear when converted to a number.

For the boolean, compare exact strings. Boolean("false") is true because the string is nonempty, as MDN’s Boolean reference explains. Our rule accepts only lowercase true or false and converts them explicitly. The frozen result contains only a number and a boolean, keeping the rest of the program away from raw configuration text.

Run with defaults and overrides

Remove both example variables from this command’s environment:

env -u DEMO_PORT -u DEMO_VERBOSE node read-environment-config.mjs

Output:

Port: 3000
Verbose: false

Now provide both values for one run:

env DEMO_PORT=4200 DEMO_VERBOSE=true node read-environment-config.mjs

Output:

Port: 4200
Verbose: true

Both successful runs exit with status 0. The env command avoids permanently exporting or unsetting anything in your current shell.

Load a small environment file

Node can load a file before your JavaScript starts. Save this nonsecret example as demo-config.env:

DEMO_PORT=5000
DEMO_VERBOSE=false

Run it with the file option before the script filename:

env -u DEMO_PORT -u DEMO_VERBOSE node --env-file=demo-config.env read-environment-config.mjs

Output:

Port: 5000
Verbose: false

A variable already present in the process environment takes precedence over the file. Verify that with a one-command override:

env -u DEMO_VERBOSE DEMO_PORT=6000 node --env-file=demo-config.env read-environment-config.mjs

Output:

Port: 6000
Verbose: false

The file path is relative to the current directory. Node does not automatically load a file merely because it is named .env; this example explicitly selects it. See the Node v24.19.0 env-file option.

Use only an environment file you trust: it can also contain settings that affect Node itself. Keep credentials out of tutorial files, terminal commands, logs, and committed source. Never print the entire process.env object while debugging. This example prints only its two nonsecret settings.

Reject bad values before doing work

Check an out-of-range port. The if statement makes the expected failure safe to inspect even with Bash’s set -e enabled:

if env DEMO_PORT=0 DEMO_VERBOSE=false node read-environment-config.mjs; then
  printf 'Unexpected success\n'
else
  printf 'Exit status: %s\n' "$?"
fi

Output, including standard error:

Configuration error: DEMO_PORT must be between 1 and 65535.
Exit status: 2

Check an ambiguous boolean spelling:

if env DEMO_PORT=3000 DEMO_VERBOSE=yes node read-environment-config.mjs; then
  printf 'Unexpected success\n'
else
  printf 'Exit status: %s\n' "$?"
fi

Output:

Configuration error: DEMO_VERBOSE must be true or false.
Exit status: 2

An empty port or a value such as 3000abc fails the digits check. 65536 fails the range check. Both boundaries, 1 and 65535, are accepted. Validate once at startup, before connecting to services or writing application data, so a bad setting cannot leave work half done.

Clean up

Remove the two tutorial files and the empty directory:

rm -- read-environment-config.mjs demo-config.env
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

Acknowledgements

This post was created with assistance from AI.

Last updated on