Your First Node.js Program
With Node.js installed, the fastest way to understand it is to write something and run it. Node executes JavaScript directly on your machine using the same V8 engine that powers Chrome, so there is no browser, no HTML, and no build step required. In this guide you’ll create a script, print to the terminal with console.log, read command-line arguments with process.argv, and try the interactive REPL.
Creating hello.js
Create a new file named hello.js in an empty folder. The .js extension tells Node it contains JavaScript. Start with the canonical first program:
console.log("Hello, Node.js!");
console.log writes a line of text to standard output (your terminal). It is part of the global console object, which Node provides automatically — you do not import it. Internally Node sends this to process.stdout, but console.log is the friendly, everyday API you’ll reach for constantly.
Running the script
Open a terminal in the folder containing hello.js and run it with the node command followed by the filename:
node hello.js
Output:
Hello, Node.js!
That’s it — Node read the file, executed it top to bottom, printed the line, and exited. You can pass the file by relative or absolute path, and the .js extension is optional when there’s no ambiguity (node hello also works).
Tip: Run
node --version(ornode -v) at any time to confirm which version is active. Stick to an even-numbered LTS release such as 20.x or 22.x for production work — odd-numbered releases are short-lived and meant for early testing.
Doing a little more than hello
A single log line is a fine start, but real scripts compute things. Node supports modern JavaScript out of the box, including async/await, the native fetch API, and ES modules. Here is a slightly richer script that uses a function and a template literal:
function greet(name) {
return `Hello, ${name}! It is ${new Date().getFullYear()}.`;
}
console.log(greet("developer"));
Output:
Hello, developer! It is 2026.
Nothing here is Node-specific — it’s plain JavaScript. The point is that you author it in a file and Node runs it immediately, with no transpiler in the loop.
Reading command-line arguments
Most useful CLI scripts accept input. Node exposes the arguments passed on the command line through process.argv, an array of strings. The first two entries are always the path to the Node executable and the path to your script; the actual user arguments begin at index 2.
// args.js
const args = process.argv.slice(2);
if (args.length === 0) {
console.log("Usage: node args.js <name> [more names...]");
process.exit(1);
}
for (const name of args) {
console.log(`Hello, ${name}!`);
}
Run it with some arguments:
node args.js Ada Linus Grace
Output:
Hello, Ada!
Hello, Linus!
Hello, Grace!
Using .slice(2) is the standard idiom to skip the executable and script paths so you’re left with just what the user typed. process.exit(1) ends the program with a non-zero status code, signalling failure to the shell — useful for scripts and CI pipelines.
Index in process.argv | Example value | Meaning |
|---|---|---|
0 | /usr/local/bin/node | Path to the Node binary |
1 | /home/you/args.js | Path to your script |
2+ | Ada, Linus, Grace | Your actual arguments |
Note:
process.argvgives you raw strings with no parsing of flags like--name=value. For anything beyond a couple of positional arguments, reach for the built-innode:utilparseArgshelper or a library such as Commander rather than hand-rolling a parser.
CommonJS vs. ES modules
The examples above run fine as-is because they use only globals. The moment you import other modules, the module system matters. Node supports two:
// ES modules — use when "type": "module" is set in package.json, or .mjs files
import process from "node:process";
// CommonJS — the historical default, used in .cjs files or without "type": "module"
const process = require("node:process");
Modern projects should prefer ES modules (import/export). Add "type": "module" to your package.json, or name files .mjs, to opt in. Core modules are referenced with the node: prefix (node:fs, node:path) to make their origin explicit and avoid clashes with npm packages.
Trying the REPL
Node also ships an interactive prompt called the REPL (Read-Eval-Print Loop). Run node with no filename to enter it:
node
Output:
Welcome to Node.js v22.11.0.
Type ".help" for more information.
> 2 + 2
4
> const name = "Node"
undefined
> `Hi ${name}`
'Hi Node'
> .exit
The REPL evaluates each line and immediately prints the result, which makes it ideal for testing an expression, inspecting an API, or doing quick math. Press Ctrl+C twice or type .exit to leave. It’s a scratchpad, not a place to build programs — for anything you want to keep, put it in a .js file.
Best Practices
- Save reusable logic in
.jsfiles and run them withnode file.js; keep the REPL for quick experiments only. - Always
process.argv.slice(2)to read user arguments, never index from0. - Prefer ES modules (
import/export) and thenode:prefix for core modules in new projects. - Exit with
process.exit(1)(or throw) on error conditions so shells and CI detect failures. - Use
console.logfor normal output andconsole.errorfor errors so they route to the correct stream. - Pin to an even-numbered LTS release (20.x / 22.x) and verify with
node -vbefore running scripts.