These are the commands you use every day while writing and debugging Node code.
The simplest way to run code is node app.js. Node executes the file top to bottom, then keeps the process alive as long as there is pending work — an open server, a timer, an unfinished read. When nothing is left, the process exits on its own.
Running node with no arguments opens the REPL (read–eval–print loop). It is ideal for poking at an API:
_holds the last result;.helplists commands;.editorlets you paste multi-line code;.exitor Ctrl+D quits.- Top-level
awaitworks, and built-in modules are preloaded: typefs.and press Tab.
For quick one-offs use -e (evaluate) or -p (evaluate and print):
node -p "os.cpus().length"
node -e "console.log(process.versions.v8)"During development, node --watch app.js restarts the process whenever the file or anything it imports changes — no nodemon needed. Combine it with --watch-path=./src to watch a directory.
Useful companions:
node --run devruns thedevscript frompackage.json, faster thannpm runbecause it skips npm's startup.node --check file.jsonly parses the file, catching syntax errors.node --env-file=.env app.jsloads environment variables (covered later).
Since 22.18 Node can also run TypeScript files directly by stripping type annotations (node app.ts); it does not type-check, so keep tsc in your workflow for that.
Finally, a Unix script can start with the shebang #!/usr/bin/env node; mark it executable (chmod +x) and it runs like any other command.
Example
#!/usr/bin/env node
// greet.js — try: node greet.js, then node --watch greet.js and edit the text
const name = process.argv[2] ?? "world";
console.log(`Hello, ${name}!`);
// Pending timers keep the process alive; it exits after this fires
setTimeout(() => console.log("bye"), 500);
/* In a terminal:
$ node greet.js Ada -> Hello, Ada! (then "bye")
$ node -p "2 ** 10" -> 1024
$ node -> opens the REPL; try: await fetch('https://example.com').then(r => r.status)
*/Remember
node file.jsruns a script; the process exits when no work is pending- The REPL supports top-level await and has built-in modules preloaded
--watchrestarts on changes;--runruns package.json scripts quickly
Watch out for
- Thinking
--watchor type stripping type-checks or bundles code — they only restart and strip.