Environment Variables and CLI Arguments
Node.js programs often receive input from outside the source code.
Two common sources are:
- environment variables
- command-line arguments
These are especially useful for scripts, tools, and backend apps.
Why External Configuration Matters
Avoid hard-coding values that change by environment.
// Avoid
const databaseUrl = "postgres://user:password@example.com/app";This is risky because:
- secrets may be committed to git
- local and production settings are different
- deployments become harder to configure
- rotating credentials becomes painful
Use environment variables for values that differ between machines or deployments.
Reading Environment Variables
Environment variables are available on process.env.
const nodeEnv = process.env.NODE_ENV || "development";
console.log(`Environment: ${nodeEnv}`);Every value from process.env is a string or undefined.
const port = Number(process.env.PORT || 3000);
console.log(port);Convert values when you need numbers or booleans.
Setting Environment Variables
On macOS and Linux shells:
PORT=4000 node app.jsThen read it:
const port = Number(process.env.PORT || 3000);
console.log(`Using port ${port}`);For longer-running projects, teams often use deployment configuration, shell profiles, or .env files loaded by tooling.
Do not commit real secrets in .env files.
Required Configuration
If a value is required, fail early with a useful error.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error("Missing required environment variable: API_KEY");
}This is better than letting the program fail later with a confusing error.
Boolean Environment Values
Environment variables are strings.
This can surprise beginners.
process.env.DEBUG = "false";
console.log(Boolean(process.env.DEBUG)); // trueThe string "false" is truthy.
Parse booleans explicitly.
const debug = process.env.DEBUG === "true";Command-Line Arguments
Command-line arguments are values passed after the script name.
Run:
node greet.js AdaRead:
const name = process.argv[2] || "friend";
console.log(`Hello, ${name}!`);process.argv includes:
- the Node executable path
- the script path
- your custom arguments
That is why user arguments start at index 2.
Multiple Arguments
Example:
node add.js 2 3Script:
const first = Number(process.argv[2]);
const second = Number(process.argv[3]);
console.log(first + second);Output:
5Validate arguments before using them.
if (Number.isNaN(first) || Number.isNaN(second)) {
console.error("Usage: node add.js <number> <number>");
process.exitCode = 1;
} else {
console.log(first + second);
}Flags
Simple scripts may parse flags manually.
node app.js --name Ada --verboseBasic parsing:
const args = process.argv.slice(2);
const verbose = args.includes("--verbose");
const nameIndex = args.indexOf("--name");
const name = nameIndex === -1 ? "friend" : args[nameIndex + 1];
if (verbose) {
console.log("Verbose mode enabled");
}
console.log(`Hello, ${name}`);For serious CLIs, use a package designed for argument parsing.
Standard Input and Output
Node processes can communicate through standard streams:
process.stdinprocess.stdoutprocess.stderr
You already use stdout through console.log().
process.stdout.write("Normal output\n");
process.stderr.write("Error output\n");Use stderr for errors so other tools can separate normal output from error messages.
Exit Codes
Set an exit code when a script fails.
if (!process.env.API_KEY) {
console.error("Missing API_KEY");
process.exitCode = 1;
}This matters for automation, CI, and shell scripts.
A successful command exits with 0.
A failing command should exit with a non-zero code.
Security Cautions
Environment variables can contain secrets.
Do not print secrets in logs.
// Avoid
console.log(process.env.API_KEY);Command-line arguments may be visible in shell history or process lists.
Avoid passing highly sensitive secrets as CLI arguments.
Prefer secret managers, deployment configuration, or environment variables depending on your platform.
Always validate file paths, URLs, and commands that come from user input.
Common Mistakes
Do not assume an environment variable exists.
Do not forget that environment variables are strings.
Do not use Boolean(process.env.FLAG) for "false" values.
Do not ignore invalid CLI arguments.
Do not log secrets while debugging.
Summary
Use process.env for environment-specific configuration and process.argv for command-line input.
Convert values to the right type, validate required inputs, use meaningful exit codes, and keep secrets out of source code and logs.