CLI Env and Config
Building scripts and services configuration from env, files, and CLI flags. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Search across all documentation pages
Building scripts and services configuration from env, files, and CLI flags. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Minimal flag parsing with util.parseArgs in modern Node.
import { parseArgs } from "node:util";
const { values, positionals } = parseArgs({
args: ["--port", "3000", "file.txt"],
options: { port: { type: "string" }, verbose: { type: "boolean" } },
allowPositionals: true,
});
values.port // "3000"
positionals[0] // "file.txt"Load .env in development - never commit secrets; prefer platform env in production.
// import "dotenv/config";
process.env.DATABASE_URL = process.env.DATABASE_URL ?? "postgres://local/db";
Boolean(process.env.DATABASE_URL) // trueRead a JSON config and validate required keys early.
const cfg = JSON.parse('{"port":8080}') as { port: number };
cfg.port // 8080Support cat f | node tool.js by reading stdin when no file arg is given.
const input = "hello from pipe";
input.length // 15
// real CLI: read process.stdin when positionals emptyUse non-zero exit codes for CLI failures so shells and CI detect errors.
process.exitCode = 0;
process.exitCode // 0
// catch: process.exitCode = 1Branch behavior carefully on NODE_ENV - prefer explicit feature flags when possible.
const isProd = process.env.NODE_ENV === "production";
typeof isProd // "boolean"Document flags on --help for operator ergonomics.
const args = ["--help"];
const help = args.includes("--help");
help // true
// if (help) { console.log("Usage: ..."); process.exit(0); }Env vars are strings - coerce and validate numbers/booleans.
const port = Number(process.env.PORT ?? "3000");
Number.isFinite(port) // true
port // 3000 when PORT unsetTypical precedence: defaults < file < env < CLI flags.
const filePort = 8080;
const envPort = process.env.PORT ? Number(process.env.PORT) : undefined;
const cliPort = 9000 as number | undefined;
const port = cliPort ?? envPort ?? filePort ?? 3000;
port // 9000Make a script executable with a node shebang (install entry via package bin).
// #!/usr/bin/env node
// at top of dist/cli.js
"node".length // 4Expose CLIs via package.json bin for npm/pnpm installs.
const pkg = { bin: { mytool: "./dist/cli.js" } };
pkg.bin.mytool // "./dist/cli.js"Respect NO_COLOR and TTY when printing ANSI colors.
const color = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
const red = (s: string) => (color ? `\x1b[31m${s}\x1b[0m` : s);
red("err").includes("err") // trueResolve user paths against process.cwd() not the module dir.
import path from "node:path";
const file = path.resolve(process.cwd(), "notes.txt");
path.isAbsolute(file) // trueReject unexpected enum values early at boot.
const level = process.env.LOG_LEVEL ?? "info";
["debug", "info", "warn", "error"].includes(level) // true for defaultRe-read config on SIGHUP in long-running daemons when appropriate.
// process.on("SIGHUP", () => { void reloadConfig(); });
typeof process.on // "function"Stack versions: Node.js 24.18.0 (LTS line 24) · TypeScript 5.6+ · npm 10+
Reviewed by Chris St. John·Last updated Jul 18, 2026