The Node CLI is more than just node app.js. It’s an interactive playground, a debugger entry point, and a quick scripting tool. Knowing the useful flags saves us a lot of time.
REPL — Read Eval Print Loop
Type node with no arguments and we get an interactive JS shell. Same engine, same APIs as Node, but live.
$ node
Welcome to Node.js v20.11.0.
> 1 + 1
2
> const fs = require("node:fs")
undefined
> fs.readdirSync(".")
[ 'package.json', 'index.js', 'README.md' ]
> .exit
Handy for trying out an API, checking date math, or testing a regex without making a file.
REPL dot commands
Inside the REPL, commands starting with . are special:
.help— list all commands.editor— multi-line editor mode (Ctrl+D to finish).load file.js— evaluate a file’s contents into the REPL.save out.js— save the session to a file.break/.clear— abandon current multi-line input.exit(or Ctrl+D twice) — quit
Useful REPL tricks
_holds the result of the last expression._errorholds the last thrown error.- Tab completion works on variables and properties.
- Top-level
awaitworks — no need to wrap in an async function.
> await fetch("https://api.github.com")
> _.status
200
Common CLI flags
-e and -p — quick one-liners
-e evals a string. -p does the same but prints the result. Great for tiny shell utilities.
# Get a UUID without installing anything
node -p "crypto.randomUUID()"
# d8e7c2a0-...
# Quickly check Node version programmatically
node -p "process.version"
# Read JSON from stdin and pretty-print
cat data.json | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.stringify(JSON.parse(s),null,2)))"
—watch — built-in nodemon
Since Node 18.11, we don’t need nodemon for most cases. --watch restarts our process when watched files change.
node --watch server.js
# Watching for file changes...
We can also pass --watch-path=./src to scope it.
—inspect — debugging
Adds a debugger that DevTools can attach to. Open chrome://inspect in Chrome and we see our Node process. Or use VS Code’s “Attach to Node” config.
node --inspect server.js
# Debugger listening on ws://127.0.0.1:9229/...
node --inspect-brk server.js
# Same, but the program pauses on line 1 waiting for us to attach
—env-file — built-in dotenv
Node 20.6+ ships with a built-in .env loader. We no longer need the dotenv package for simple cases.
node --env-file=.env server.js
Inside our code, the variables show up on process.env like normal.
process.argv — reading CLI args
When we write our own CLIs, args come in via process.argv. The first two entries are the node binary and the script path.
// node greet.js Manish
console.log(process.argv);
// [ '/usr/bin/node', '/path/to/greet.js', 'Manish' ]
const name = process.argv[2];
console.log(`Hello, ${name}`);
For anything more than one arg, reach for node:util’s parseArgs (Node 18+) or the commander / yargs packages.
const { parseArgs } = require("node:util");
const { values } = parseArgs({
options: {
port: { type: "string", short: "p", default: "3000" },
dev: { type: "boolean" },
},
});
console.log(values); // { port: '8080', dev: true }