Chapter 5 of 17
~12 minThe process Object & Environment Config
The `process` global is your window into the running Node.js program itself - its environment variables, command-line arguments, and lifecycle. Using it well is what lets the same code run correctly across development, staging, and production.
process.env, process.argv, and process.cwd
`process.env` is an object holding every environment variable the OS passed to the Node.js process - this is the standard way to inject configuration (database URLs, API keys, feature flags) without hardcoding them in source. `process.argv` is an array of command-line arguments, where index 0 is the path to the `node` binary and index 1 is the path to the running script, so your own arguments start at index 2. `process.cwd()` returns the directory the process was launched from, which is not necessarily the same as `__dirname` (the directory of the current file).
// run with: PORT=4000 node server.js --verbose console.log('PORT:', process.env.PORT || 3000); console.log('argv:', process.argv); // ['/usr/bin/node', '/app/server.js', '--verbose'] const args = process.argv.slice(2); const verbose = args.includes('--verbose'); console.log('verbose mode:', verbose); console.log('cwd:', process.cwd());
NODE_ENV and Managing Config Across Environments
`NODE_ENV` is a widely-adopted (though not Node.js-enforced) convention for signaling which environment code is running in - typically `development`, `test`, or `production`. Many popular libraries (Express, various logging and ORM packages) check it to decide whether to enable verbose debugging output, cache templates, or turn on performance optimizations.
A common pattern is to keep a `.env` file per environment (loaded via a package like `dotenv` in development, and provided directly by the hosting platform in production) so the same code reads `process.env.DATABASE_URL` everywhere, with only the underlying value changing.
require('dotenv').config(); // loads .env into process.env in development const config = { port: Number(process.env.PORT) || 3000, databaseUrl: process.env.DATABASE_URL, isProduction: process.env.NODE_ENV === 'production', }; if (!config.databaseUrl) { console.error('Missing required DATABASE_URL environment variable'); process.exit(1); } module.exports = config;
process.exit and Exit Codes
`process.exit(code)` terminates the process immediately - `0` conventionally means success and any non-zero code signals failure, which matters to shell scripts, CI pipelines, and process managers that branch on exit status. Calling `process.exit()` abruptly can cut off pending asynchronous work (like an in-flight write or console.log flush), so it is best reserved for genuine startup failures rather than routine control flow.
Graceful Shutdown via SIGTERM
When a process manager, container orchestrator, or `kill` command asks a process to stop, it typically sends the `SIGTERM` signal first (giving the app a chance to clean up) before escalating to `SIGKILL` (which cannot be intercepted). Listening for `SIGTERM` lets a server close its HTTP listener, finish in-flight requests, close database connections, and only then exit - avoiding dropped connections or corrupted writes during a deploy or a scale-down event.
const http = require('http'); const server = http.createServer((req, res) => { res.end('ok'); }); server.listen(3000, () => console.log('listening on 3000')); process.on('SIGTERM', () => { console.log('SIGTERM received, shutting down gracefully...'); server.close(() => { console.log('all connections closed, exiting'); process.exit(0); }); // safety net: force-exit if close() hangs too long setTimeout(() => process.exit(1), 10_000).unref(); });
Coding challenge
Write a script that reads a --name value from the command line (e.g. node greet.js --name=Sam), falls back to process.env.DEFAULT_NAME if not provided, and exits with code 1 and an error message if neither is set.
// Write your solution here
Answer every question below to mark this chapter as complete.
Quiz Yourself
Score: 0/51. In `process.argv`, what do the first two elements represent?
2. What is the standard purpose of the NODE_ENV environment variable?
3. Why should you generally avoid calling `process.exit()` in the middle of routine async logic?
4. What is the purpose of listening for the SIGTERM signal in a server process?
5. What does `process.cwd()` return, and how does it differ from `__dirname`?