process & Environment Variables
Every running Node.js program has a global object called process. It describes the program itself: which version of Node.js runs it, which arguments you typed, which folder it started in, and the environment variables it can read. It also lets the program exit with a success or failure code and react when someone presses Ctrl+C.
The most important part for web developers is configuration. Your database password, your port number and your API keys must not be written into the code. In this lesson you will read them from environment variables, load them from a .env file with the built-in --env-file option, and check them when the program starts.
Facts about the running program
console.log(`Node.js ${process.version}`);
console.log(`Platform: ${process.platform}, CPU: ${process.arch}`);
console.log(`Folder: ${process.cwd()}`);
const mb = (bytes) => `${Math.round(bytes / 1024 / 1024)} MB`;
console.log(`Memory used: ${mb(process.memoryUsage().rss)}`);
console.log(`Running for: ${process.uptime().toFixed(2)} s`);Node.js v26.13.0 Platform: win32, CPU: x64 Folder: C:\node-course Memory used: 50 MB Running for: 0.74 s
process.cwd() is the current working directory, the folder you ran the command from. memoryUsage().rss is the total memory the process uses. Your numbers will be different.
Command-line arguments
process.argv is an array of everything on the command line. The first two items are the path to node and the path to your script; your own arguments start at index 2.
// args.js
console.log(process.argv);
const [, , ...args] = process.argv;
console.log(args);node args.js Kochi 3 --fast[ 'C:\\Program Files\\nodejs\\node.exe', 'C:\\node-course\\args.js', 'Kochi', '3', '--fast' ] [ 'Kochi', '3', '--fast' ]
Every argument is a string, even 3. For anything more than one or two arguments, use the built-in parseArgs() from node:util. It understands options such as --city Lucknow and short forms such as -t 2:
// greet.js
import { parseArgs } from "node:util";
const { values, positionals } = parseArgs({
options: {
city: { type: "string", short: "c", default: "Delhi" },
times: { type: "string", short: "t", default: "1" },
shout: { type: "boolean", short: "s" },
},
allowPositionals: true,
});
const name = positionals[0] ?? "friend";
let message = `Namaste ${name} from ${values.city}!`;
if (values.shout) message = message.toUpperCase();
for (let i = 0; i < Number(values.times); i++) console.log(message);node greet.js Farhan --city Lucknow -t 2
node greet.js Isha -sNamaste Farhan from Lucknow! Namaste Farhan from Lucknow! NAMASTE ISHA FROM DELHI!
An unknown option such as --colour throws an error with the code ERR_PARSE_ARGS_UNKNOWN_OPTION, so typing mistakes do not pass silently. Positionals are the arguments that are not options, here the name.
Environment variables
An environment variable is a named setting that the operating system gives to every program it starts. Node.js puts them all in process.env. They let the same code run with different settings on your laptop, on a test server and in production, and they keep secrets out of your source code.
// config.js
const port = Number(process.env.PORT ?? 3000);
const mode = process.env.NODE_ENV ?? "development";
const dbHost = process.env.DB_HOST ?? "127.0.0.1";
console.log(`Port: ${port} (${typeof port})`);
console.log(`Mode: ${mode}`);
console.log(`DB host: ${dbHost}`);
console.log(`DB password set: ${Boolean(process.env.DB_PASSWORD)}`);Set variables for one run in the terminal. The syntax depends on your shell:
# macOS, Linux, Git Bash
PORT=8080 NODE_ENV=production node config.js# Windows PowerShell (stays set until you close the window)
$env:PORT = "8080"; $env:NODE_ENV = "production"; node config.jsPort: 8080 (number) Mode: production DB host: 127.0.0.1 DB password set: false
Values in process.env are always strings (or undefined if not set), so convert numbers with Number() and give defaults with ??. Never print secret values in logs; print only whether they are set, as the code above does. NODE_ENV is a common convention: many libraries, including Express, behave differently when it is "production".
.env files and --env-file
Typing many variables every time is tiring. Instead, keep them in a file called .env in the project folder:
# .env: settings for local development
PORT=4000
DB_HOST=127.0.0.1
DB_PASSWORD="s3cret pass" # quotes keep the spaceNode.js can load it for you with the --env-file option. No package is needed:
node --env-file=.env config.jsPort: 4000 (number) Mode: development DB host: 127.0.0.1 DB password set: true
Useful rules:
- Lines starting with
#are comments, and so is text after#at the end of a line. Wrap values in quotes when they contain spaces or#. - A variable that is already set in the real environment wins over the file. Running
PORT=9000 node --env-file=.env config.jsuses port 9000. This lets a server override the file. - You can pass several files:
--env-file=.env --env-file=.env.local. Later files override earlier ones. --env-filestops with an error if the file is missing. Use--env-file-if-exists=.envwhen the file is optional, for example in production where real variables are used instead.
To load a file from inside your code, call process.loadEnvFile(). With no argument it reads .env in the current folder.
Checking configuration at startup
A server that starts without its database password fails later in confusing ways. Check the required settings first and stop with a clear message:
try {
process.loadEnvFile(); // reads ./.env
} catch {
console.log("No .env file, using defaults");
}
const required = ["DB_HOST", "DB_PASSWORD", "JWT_SECRET"];
const missing = required.filter((name) => !process.env[name]);
if (missing.length > 0) {
console.error(`Missing environment variables: ${missing.join(", ")}`);
process.exitCode = 1;
} else {
console.log("Configuration OK");
}Missing environment variables: JWT_SECRET
Exit codes and shutting down
When a program ends, it returns an exit code to the system: 0 means success and any other number means failure. Scripts, test tools and process managers read it. Setting process.exitCode = 1 marks the run as failed but lets Node.js finish its pending work and exit normally. process.exit(1) stops immediately, which can cut off logs that have not been written yet, so prefer exitCode.
Servers should also stop gracefully: finish the requests in progress and close database connections when someone presses Ctrl+C (the SIGINT signal) or a hosting platform asks the process to stop (SIGTERM):
function shutdown(signal) {
console.log(`${signal} received, closing the server...`);
server.close(() => {
console.log("All connections closed. Bye!");
});
}
process.on("SIGINT", shutdown);
process.on("SIGTERM", shutdown);Here server is the HTTP server you will create in The http Module.
Common mistakes
- Writing secrets in code. Passwords in source files end up on GitHub. Read them from
process.env. - Forgetting values are strings.
process.env.DEBUG === trueis always false; compare with"true", and convert numbers withNumber(). - Committing
.env. Put it in.gitignoreand share a.env.exampleinstead. - Using
export PORT=8080in PowerShell. That is bash syntax. PowerShell uses$env:PORT = "8080". - Calling
process.exit()too early. It can drop unwritten output. Setprocess.exitCodeand let the program finish.
Key points
processdescribes the running program:version,platform,cwd(),memoryUsage()and more.process.argvholds command-line arguments from index 2;parseArgs()fromnode:utilparses options properly.process.envholds environment variables; every value is a string orundefined.node --env-file=.env app.jsloads a.envfile with no package; real environment variables take priority.- Check required settings at startup, keep
.envout of Git, and preferprocess.exitCodeoverprocess.exit().
Exercise
Write server-config.js that reads PORT (default 3000), SHOP_NAME (default "My Shop") and MAX_UPLOAD_MB (default 5) from the environment, converts the numbers, and prints them. Create a .env file that sets SHOP_NAME to Ananya Handlooms, Kochi and MAX_UPLOAD_MB to 10, then run the program with --env-file.
Show solution
// server-config.js
const config = {
port: Number(process.env.PORT ?? 3000),
shopName: process.env.SHOP_NAME ?? "My Shop",
maxUploadMb: Number(process.env.MAX_UPLOAD_MB ?? 5),
};
console.log(config);# .env contains:
# SHOP_NAME="Ananya Handlooms, Kochi"
# MAX_UPLOAD_MB=10
node --env-file=.env server-config.js{ port: 3000, shopName: 'Ananya Handlooms, Kochi', maxUploadMb: 10 }PORT is not in the file, so the default is used. The quotes in .env are removed when the file is loaded.
Quick Quiz
1. Your script is run as node app.js Pune. Where is "Pune"?
Index 0 is the node program and index 1 is the script path, so your arguments start at index 2.
2. What type is process.env.PORT when it is set to 8080?
Environment variables are always strings; convert them with Number().
3. .env sets PORT=4000, and you run PORT=9000 node --env-file=.env app.js. Which port is used?
--env-file does not overwrite variables that are already set in the environment.
4. Why is process.exitCode = 1 usually better than process.exit(1)?
process.exit() stops at once and can cut off unwritten output.
Learn Node.js with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
