The process Object
Reviewed & published by Brayan K
The process object is a built-in global that connects your Node program to the operating system, exposing command-line arguments, environment variables, the working directory, and methods to read input and control how the program exits.
Part of the free Node.js course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
By the end of this lesson you'll be able to read arguments with process.argv, pull configuration from process.env, find the working directory, detect the platform, write to stdout, and stop your program cleanly with the right exit code.
What You'll Learn in This Lesson
- How to read command-line arguments with process.argv
- How to read configuration from process.env with fallbacks
- What process.cwd() returns and how it differs from a file path
- How to detect the operating system with process.platform
- How process.stdout.write differs from console.log
- How to stop a program cleanly with process.exit(code)
1️⃣ Command-Line Arguments: process.argv
process.argv is an array describing how your program was launched. The first two entries are fixed — the path to node and the path to your script — so your own arguments start at index 2.
The standard move is process.argv.slice(2), which drops those two fixed entries and gives you a clean array of just the values the user typed.
// process.argv is an array of the command-line pieces:
// [0] = path to node, [1] = path to your script, [2+] = your args
//
// Normally you would run: node greet.cjs Alice 42
// The Run button here starts the file with no arguments, so this line
// stands in for that command line. Everything below behaves exactly as it
// would if you had typed the two words yourself.
process.argv.push('Alice', '42');
console.log(process.argv.length); // -> 4
console.log(process.argv[2]); // -> Alice
console.log(process.argv[3]); // -> 42
// To get JUST your arguments, slice off the first two:
const args = process.argv.slice(2);
console.log(args); // -> [ 'Alice', '42' ]2️⃣ Environment Variables: process.env
process.env exposes the environment variables as an object of strings. This is the standard place to keep configuration that changes between machines — ports, API keys, database URLs — so it lives outside your code.
A variable that wasn't set reads as undefined, so the common pattern is a fallback: const port = process.env.PORT || '3000'.
// process.env holds the environment variables as an object of STRINGS.
//
// Normally you would run: GREETING=hello node config.cjs
// Standing in for that here, because the Run button sets no variables —
// and note the value is a STRING, which is the point of the line after it.
process.env.GREETING = 'hello';
console.log(process.env.GREETING); // -> hello
// A variable that wasn't set is undefined. Provide a fallback with ||:
const port = process.env.PORT || '3000';
console.log(`Port: ${port}`); // -> Port: 30003️⃣ Platform, Output & Exiting
process.platform returns the OS family ('linux', 'darwin', or 'win32'), handy for cross-platform behaviour. process.cwd() returns the directory you ran the command from, which isn't always where the file lives.
process.stdout.write prints text with no trailing newline (unlike console.log). And process.exit(code) stops the program immediately — 0 for success, non-zero for failure — so any code after it never runs.
// process.platform tells you the OS family:
// 'linux', 'darwin' (macOS), or 'win32' (Windows)
const isWindows = process.platform === 'win32';
console.log(`On Windows? ${isWindows}`); // -> On Windows? false (on Linux/Mac)
// process.stdout.write prints WITHOUT a trailing newline,
// unlike console.log. Great for progress on one line.
process.stdout.write('Loading');
process.stdout.write('...');
process.stdout.write(' done\n');
// process.exit(code): 0 means success, any non-zero means failure.
// Code AFTER exit() never runs.
console.log('Exiting cleanly');
process.exit(0);
console.log('This line never runs');Your turn. Fill in the two blanks marked ___ so the program reads a name argument with a sensible fallback, then run it.
// 🎯 YOUR TURN — fill in each ___ then run it.
// Run with: node hello.cjs World
// 1) Read the first user argument (argv index 2),
// falling back to 'stranger' if none was given.
const name = process.argv[___] || ___; // 👉 index 2 , 'stranger'
console.log(`Hello, ${name}!`);
// ✅ Expected output (when run with World):
// Hello, World!Mini-Challenge: A "Double It" CLI
No blanks — just a brief and an outline. This ties together reading arguments, converting a string to a number, and exiting with the right code. Write it yourself, run it, and check your output.
// 🎯 MINI-CHALLENGE: a tiny "double it" CLI.
// Run with: node double.cjs 21
//
// 1. Read the user args with process.argv.slice(2).
// 2. If NO number was given, print an error and process.exit(1).
// 3. Otherwise convert the first arg to a Number, print its double,
// and process.exit(0).
//
// ✅ Expected output (when run with 21):
// Double is 42
// your code hereCommon Errors (and the fix)
- ❌ Your argument is "undefined" — You read argv[0] or argv[1] expecting your input. ✅ User arguments start at index 2; use process.argv.slice(2).
- ❌ Math gives weird strings like "421" — argv values are strings. ✅ Convert with Number(arg) before doing arithmetic.
- ❌ process.env.MY_VAR is undefined — The variable wasn't set in this shell. ✅ Set it (MY_VAR=x node app.js) and/or add a || 'default' fallback.
- ❌ "ENOENT" using a relative path — cwd() is where you ran node, not where the file lives. ✅ Build paths from __dirname instead.
- ❌ Code after process.exit() never runs — That's by design; exit() stops immediately. ✅ Put cleanup before the exit call, or let the program finish naturally.
Pro Tips
- 💡 Listen for Ctrl-C: process.on('SIGINT', () => { ... }) lets you save state or print a goodbye before the program stops.
- 💡 Prefer setting process.exitCode = 1 over process.exit(1) when you can — it lets pending output flush before Node quits.
- 💡 Keep config in process.env so the same code runs unchanged across your laptop, CI, and production.
📋 Quick Reference — The process Object
| Task | process Syntax |
|---|---|
| User arguments | process.argv.slice(2) |
| An env variable | process.env.PORT |
| Working directory | process.cwd() |
| OS family | process.platform |
| Print, no newline | process.stdout.write(s) |
| Stop the program | process.exit(0) |
| React to Ctrl-C | process.on('SIGINT', fn) |
🎉 Lesson Complete!
- ✅ process is a built-in global connecting your program to the OS
- ✅ process.argv.slice(2) gives you the user's command-line arguments (as strings)
- ✅ process.env holds configuration; use || 'default' for missing values
- ✅ process.platform reports the OS; process.cwd() reports where you ran the command
- ✅ process.exit(code) stops immediately — 0 for success, non-zero for failure
Practice quiz
Do you have to import the process object before using it?
- Yes, require('process')
- No, it is a built-in global
- Yes, import it from 'node:os'
- Only in ESM files
Answer: No, it is a built-in global. process is a global object Node provides automatically; you never import it.
For 'node greet.js Alice 42', what is process.argv.length?
- 4
- 2
- 3
- 1
Answer: 4. argv[0] is node, argv[1] is the script path, then 'Alice' and '42' make four entries.
At what index do your own command-line arguments start in process.argv?
- 0
- 1
- 2
- 3
Answer: 2. Index 0 is node and index 1 is the script path, so user arguments begin at index 2.
What does process.argv.slice(2) give you?
- The node path
- The script path
- Just the user-supplied arguments
- The environment variables
Answer: Just the user-supplied arguments. slice(2) drops the two fixed entries, leaving a clean array of the user's arguments.
What type are the values stored in process.env?
- Numbers
- Booleans
- Objects
- Strings
Answer: Strings. Environment variables are always strings; convert with Number() if you need a number.
What does process.env.PORT evaluate to if PORT was never set?
- undefined
- 0
- An empty string
- null
Answer: undefined. An unset variable reads as undefined, which is why the || '3000' fallback pattern is common.
What does process.exit(0) signal to whatever launched the program?
- Failure
- Success
- A warning
- Restart
Answer: Success. By convention exit code 0 means success and any non-zero value means failure.
How does process.stdout.write differ from console.log?
- It adds a trailing newline
- It only works on Windows
- It does not add a trailing newline
- It returns a Promise
Answer: It does not add a trailing newline. stdout.write prints raw text with no automatic newline, unlike console.log.
What does process.platform return on Linux?
- 'win32'
- 'linux'
- 'darwin'
- 'Linux_NT'
Answer: 'linux'. process.platform returns the OS family code: 'linux', 'darwin', or 'win32'.
What happens to code written after a process.exit() call?
- It runs after a delay
- It runs first
- It never runs
- It runs only on error
Answer: It never runs. exit() stops the program immediately, so any code after it never executes.
Continue this course
- Previous: Buffers & Binary Data
- Next: Timers & the Event Loop Phases — setTimeout, setImmediate, and process.nextTick ordering explained
- Quick reference: Node.js cheat sheet › Common Patterns
Frequently asked questions
What is the process object in Node.js?
process is a global object Node provides automatically — you never import it. It is your program's connection to the operating system and the running Node instance: it exposes the command-line arguments (process.argv), environment variables (process.env), the current working directory (process.cwd()), the platform, standard input and output streams, and methods like process.exit() to stop the program. It also emits lifecycle events such as 'exit' and signals like SIGINT.
Why does process.argv start at index 2 for my arguments?
process.argv always begins with two fixed entries: argv[0] is the full path to the node executable, and argv[1] is the full path to the script being run. Your own arguments start at index 2. That is why the common idiom is process.argv.slice(2), which drops those two fixed entries and gives you a clean array of just the user-supplied arguments.
What is the difference between process.exit(0) and process.exit(1)?
The number is the exit code the program returns to whatever launched it. By convention 0 means success and any non-zero value (1, 2, 3, ...) means failure. Shells, CI pipelines, and parent processes read this code to decide whether your script worked. Use process.exit(1) when something went wrong so callers can react; use process.exit(0) or just let the program finish for success.
What is the difference between console.log and process.stdout.write?
console.log writes its arguments and automatically adds a newline at the end, and it can format multiple values and objects nicely. process.stdout.write sends raw text with no newline added, so you control exactly what appears — useful for progress indicators on a single line or for piping precise output. Under the hood, console.log is essentially a friendlier wrapper around process.stdout.write.