Core Globals (process, __dirname)
Reviewed & published by Brayan K
Node.js provides a set of global objects available in every file without importing them — most importantly process (information and control over the running program) and __dirname and __filename (the absolute path of the current directory and file).
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 read command-line arguments and environment variables from process, build reliable file paths with __dirname, and recognise the other always-available globals like console, timers, and Buffer.
What You'll Learn in This Lesson
- What a Node global is and why no import is needed
- Read command-line arguments with process.argv
- Read environment variables with process.env
- Inspect the runtime: process.version, platform, and pid
- Use __dirname and __filename for reliable file paths
- Know the other globals: console, timers, Buffer, globalThis
1️⃣ The process Object
The process global is your program's connection to the world it runs in. It carries the arguments you were started with, the environment around you, facts about the Node runtime, and the controls to stop the program. The four pieces you'll reach for constantly:
- • process.argv — an array of command-line arguments. Index 0 is node, index 1 is your script, and your real arguments start at index 2.
- • process.env — an object of environment variables (all values are strings). A variable that isn't set reads as undefined, not an error.
- • process.version / process.platform / process.pid — read-only facts: the Node version, the OS, and this process's id number.
- • process.exit(code) — stops the program right now. 0 means success; any other number signals an error.
// process is a GLOBAL — no require/import needed, it's always there.
// process.argv is an ARRAY of command-line arguments.
// [0] is the path to node, [1] is the path to this script,
// so the arguments YOU typed start at index 2.
console.log("All argv:", process.argv);
console.log("Your args:", process.argv.slice(2)); // just the real ones
// process.env is an OBJECT of environment variables (all strings).
console.log("Home folder:", process.env.HOME); // e.g. /home/user
console.log("Missing var:", process.env.NOPE); // undefined, not an error
// A few handy read-only fields about the running program:
console.log(`Node version: ${process.version}`); // e.g. v20.11.0
console.log(`Platform: ${process.platform}`); // e.g. linux / darwin / win32
console.log(`Process id (PID): ${process.pid}`); // e.g. 48213
// process.exit(code) stops the program immediately. 0 = success.
if (process.argv.length < 3) {
console.log("No arguments given — exiting.");
process.exit(0);
}Now run that file and pass it two arguments. Watch how the words you type land in process.argv starting at index 2:
# Save the code above as app.js, then pass it some arguments:
node app.js hello 422️⃣ __dirname and __filename
These two globals tell you where the current file lives on disk, as absolute paths. __dirname is the folder, __filename is the full path including the file name. They matter because Node resolves relative paths from the current working directory (where you ran node), which can change — but __dirname never does. To open a file that sits next to your script, build the path from __dirname so it works wherever the program is launched.
// __dirname = absolute path of the FOLDER this file lives in.
// __filename = absolute path of THIS file, including its name.
// Both are global and require no import (in CommonJS files).
console.log("__dirname :", __dirname);
console.log("__filename:", __filename);
// Why they matter: paths in Node are resolved from the CURRENT WORKING
// DIRECTORY (where you ran "node"), NOT from where the file lives.
// To reliably open a file that sits NEXT to your script, build the path
// from __dirname so it works no matter where you run node from.
const path = require("path");
const configPath = path.join(__dirname, "config.json");
console.log("Config path:", configPath);
// Those three lines are absolute paths, so they differ on every machine.
// What never differs is the RELATIONSHIP between them, which is the whole
// reason to use __dirname:
console.log("config sits beside the script:", path.dirname(configPath) === __dirname);
console.log("__dirname is __filename's folder:", path.dirname(__filename) === __dirname);3️⃣ The Other Globals You'll Meet
A handful of other globals are always on hand, no import required:
- • console — printing and logging (console.log, console.error, and friends).
- • setTimeout / setInterval — run code later, once or repeatedly (cancel with clearTimeout / clearInterval).
- • Buffer — work with raw binary data (bytes), used heavily by files and networking.
- • globalThis — the single, standard global object that works the same in Node and the browser.
// console — global object for printing (you've used it already).
console.log("Plain message");
console.error("Goes to stderr, not stdout"); // for errors/warnings
// ...and notice it is MISSING from the output panel below. That panel shows
// stdout only, which is exactly what console.error is for: keeping diagnostics
// out of the data your program pipes to something else. In your terminal both
// appear, because your terminal shows you both streams.
// setTimeout / setInterval — global timer functions (no import).
setTimeout(() => console.log("Runs after ~500ms"), 500);
const id = setInterval(() => console.log("tick"), 1000);
clearInterval(id); // cancel it so it doesn't run forever
// Buffer — a global for working with raw binary data (bytes).
const buf = Buffer.from("Hi");
console.log("Bytes:", buf); // <Buffer 48 69>
console.log("Back to text:", buf.toString()); // Hi
// globalThis — the one true global object across all environments.
globalThis.appName = "MyApp";
console.log("App name:", globalThis.appName);
// ⚠️ __dirname does NOT exist in ES modules (.mjs / "type":"module").
// There you derive it from import.meta.url instead:
// import { fileURLToPath } from "url";
// import { dirname } from "path";
// const __dirname = dirname(fileURLToPath(import.meta.url));Your turn. Fill in the two blanks marked ___ so the program reads a name from the command line and greets it. Follow the 👉 hints, then run it both with and without an argument.
// 🎯 YOUR TURN — replace each ___ then run it.
// Goal: read a name from the command line and greet it.
// 1) Real arguments start at index 2 of process.argv. Grab the first one.
const name = process.argv[___]; // 👉 the index where YOUR args begin
// 2) If no name was given, fall back to "stranger".
const who = name || "___"; // 👉 a default word in "double quotes"
// 3) Print the greeting using a template literal.
console.log(`Hello, ${who}!`);
// ✅ Run it as: node greet.js Sam
// Expected output:
// Hello, Sam!
//
// ✅ Run it as: node greet.js
// Expected output:
// Hello, stranger!Mini-Challenge: A System Info Reporter
No blanks this time — just a brief and an outline. Write it yourself, run it, and check your output against the example in the comments. It pulls together process.argv, process.version, process.platform, and __dirname in one tiny program.
// 🎯 MINI-CHALLENGE: a tiny "system info" reporter
// No blanks — just a brief and an outline. Write it yourself and run it.
//
// 1. Read a label from the command line (process.argv[2]); if missing, use "Report".
// 2. Print that label as a heading.
// 3. Print the Node version (process.version).
// 4. Print the platform (process.platform).
// 5. Print the folder this script lives in (__dirname).
//
// ✅ Example run: node info.js Status
// Example output:
// === Status ===
// Node: v20.11.0
// OS: linux
// Folder: /home/user/project
// your code hereCommon Errors (and the fix)
- Reading the wrong argv index — process.argv[0] is the node binary and process.argv[1] is your script. Your real arguments start at [2]. Use process.argv.slice(2) to skip the first two cleanly.
- "__dirname is not defined" — You're in an ES module (.mjs or "type": "module"), where __dirname doesn't exist. Derive it with dirname(fileURLToPath(import.meta.url)), or rename the file to .cjs.
- Treating a missing env var as an error — An unset process.env.SOMETHING is undefined, not a crash. Guard with a default: const port = process.env.PORT || 3000;.
- Mutating process.env expecting it to persist — You can set process.env.X = "...", but it only lives for this process; it does not change your real shell environment, and the value is always coerced to a string.
- Calling process.exit() too early — process.exit() stops immediately and can cut off pending async output (logs, file writes). Let the program finish naturally where you can, instead of exiting in the middle of async work.
Pro Tips
- 💡 Slice your args: reach for process.argv.slice(2) right away so you never juggle the first two fixed entries by hand.
- 💡 Build paths, don't concatenate them: use path.join(__dirname, "file.txt") instead of string addition so it works on every OS.
- 💡 Default your env vars: a pattern like const env = process.env.NODE_ENV || "development"; keeps things running when a variable is missing.
📋 Quick Reference — Node Globals
| Goal | Global |
|---|---|
| Command-line arguments | process.argv |
| Read an environment variable | process.env.NAME |
| Node version | process.version |
| Current directory of this file | __dirname |
| Full path of this file | __filename |
| Build a path next to the script | path.join(__dirname, "x") |
| Exit the program (success) | process.exit(0) |
🎉 Lesson Complete!
- ✅ Globals like process and console are available in every file with no import
- ✅ process.argv holds command-line args; your real ones start at index 2
- ✅ process.env reads environment variables; missing ones are undefined
- ✅ process.version, process.platform, and process.exit() inspect and control the runtime
- ✅ __dirname and __filename give reliable absolute paths (CommonJS only)
- ✅ console, timers, Buffer, and globalThis are the other always-on globals
Practice quiz
Which global must be imported with require before you can use it?
- process
- console
- None of these — they are all global
- __dirname
Answer: None of these — they are all global. process, console, and __dirname are all globals available with no import in Node.
In process.argv, at what index do YOUR command-line arguments begin?
- At index 2
- At index 0
- At index 1
- At index 3
Answer: At index 2. Index 0 is the node path and index 1 is the script path, so your real args start at index 2.
What does process.env.NOPE return when that variable is not set?
- An empty string
- It throws an error
- undefined
- null
Answer: undefined. Reading a missing environment variable returns undefined rather than throwing.
What does __dirname hold?
- The absolute path of the folder the current file lives in
- The current working directory
- The file's name only
- The path to the node binary
Answer: The absolute path of the folder the current file lives in. __dirname is the absolute path of the folder containing the current file (CommonJS).
Which global is used to work with raw binary data (bytes) in Node?
- Blob
- ArrayList
- Buffer
- ByteStream
Answer: Buffer. Buffer is the global for handling raw bytes; Buffer.from('Hi') yields <Buffer 48 69>.
What does process.exit(0) signal to the operating system?
- A warning
- An error
- Success
- A restart
Answer: Success. Exit code 0 conventionally means the program finished successfully.
Which property gives the Node.js version string like v20.11.0?
- process.node
- process.version
- process.platform
- process.pid
Answer: process.version. process.version returns the running Node.js version string.
Where is __dirname NOT available?
- In CommonJS files
- In scripts run with node
- In ES modules (.mjs or type:module)
- In files using require
Answer: In ES modules (.mjs or type:module). ES modules have no __dirname; you derive it from import.meta.url instead.
What does globalThis refer to?
- The current module's exports
- The one true global object across environments
- The process object
- The console object
Answer: The one true global object across environments. globalThis is the standard reference to the global object in any JS environment.
Where does console.error write its output?
- To a log file
- To stdout
- It does nothing
- To stderr
Answer: To stderr. console.error writes to standard error (stderr), separate from stdout.
Continue this course
- Previous: The Event Loop
- Next: The fs Module — Read, write, and manage files with the built-in fs module
- Quick reference: Node.js cheat sheet
Frequently asked questions
Why don't I need to require or import process and __dirname?
They are globals — Node injects them into every module before your code runs, the same way a browser gives you window and document automatically. process, console, Buffer, setTimeout, and globalThis are true globals available everywhere. __dirname and __filename are slightly different: in CommonJS files Node wraps your code in a function and passes them in as arguments, so they feel global but are actually per-file values pointing at that exact file.
Why do my command-line arguments start at process.argv[2]?
process.argv always begins with two fixed entries: index 0 is the absolute path to the Node executable, and index 1 is the absolute path to the script being run. The arguments you actually typed come after those, starting at index 2. A common pattern is process.argv.slice(2) to get just your own arguments as a clean array.
What is the difference between __dirname and process.cwd()?
__dirname is the folder where the current file is saved and never changes. process.cwd() is the current working directory — the folder you were in when you ran the node command — and it can be different every time. For reading files that ship next to your script (like a config file), use path.join(__dirname, 'config.json') so it works no matter where node was launched from.
Why is __dirname undefined in my ES module?
__dirname and __filename only exist in CommonJS modules. In ES modules (files ending in .mjs, or a project with "type": "module" in package.json) they are not defined. Instead you build them from import.meta.url, for example: const __dirname = dirname(fileURLToPath(import.meta.url)); using the url and path modules.