Skip to content
aviral gupta

// B1.2 · ~32 min · Beginner

The node command, the REPL and --watch

After this lesson you can run JavaScript with node as a file, a string or a REPL session, find out which Node.js version runs it, and restart your program on every save.

Lesson 2 of 5 in B1 Running Node and project basics

You will be able to

  • Run code with node main.js, node -e and node -p, and read the version with node --version or process.version
  • Use the REPL: see values without console.log, reuse _, type multi-line code and leave it again
  • Restart a program on every save with --watch, and predict what --watch-path watches
  1. Warm-up · Activity 1 of 7

    Warm-up: which of these commands open the REPL, where you type JavaScript one line at a time? Pick all that apply.

    Select all that apply.

  2. Predict · Activity 2 of 7

    Predict before you read on. You start node and type these two lines, pressing Enter after each. What does the REPL print after the second line?

    6 * 7
    _ + 1
  3. Practice · Activity 3 of 7

    Fill in the flag so that the command prints 1024, the value of the expression, without any console.log.

    node ____ "2 ** 10"
    node "2 ** 10"
  4. Practice · Activity 4 of 7

    Match each command to what it does.

  5. Practice · Activity 5 of 7

    In the REPL you type the first line and press Enter. The REPL waits for more, so you type the other two. What does it print?

    [1, 2, 3].forEach((n) => {
      console.log(n * 10)
    })
  6. Brain teaser · Activity 6 of 7

    Brain teaser. main.js imports ./greet.js, which is not in src. You start the command below, save a change to greet.js, then save a new file src/notes.txt. How many times does main.js restart?

    node --watch-path=src main.js
  7. Apply · Activity 7 of 7

    Mini-task. In a new folder, create package.json with "type": "module" and a "dev" script that runs node --watch main.js, and a main.js that prints one line. Start it with node --run dev, change the line in main.js and save. Check that the terminal says Restarting and shows the new line. Then run node --version in a second terminal and write down the version you use.

    Check your work against this list

Build it yourself

Read the worked example, then write the exercises. Your code runs in your browser or on your computer and is never uploaded.

Worked example

Which Node.js is running?

Before you debug anything, check which Node.js runs your code. This program asks the running process. process.version is the same string that node --version prints, process.versions lists the versions of Node.js and the parts built into it, such as the V8 JavaScript engine, and process.release.lts names the long-term-support line. The output below comes from Node.js 24.21.0; your computer shows its own version.

main.js

// Which Node.js is running this file? The process object knows.
console.log("version:", process.version);
console.log("without the v:", process.versions.node);
console.log("V8 engine:", process.versions.v8);
console.log("LTS name:", process.release.lts);

Run it with

node main.js

Output

version: v24.21.0
without the v: 24.21.0
V8 engine: 13.6.233.17-node.53
LTS name: Krypton
  • process.version starts with a v; process.versions.node is the same version without it.
  • process.versions.v8 is the version of V8, the JavaScript engine that runs your code.
  • Krypton is the name of the Node.js 24 LTS line. On a Current release, which is not LTS, process.release.lts is undefined.
  • node --version in the same terminal prints the same v24.21.0: it is the same node.

Exercises

Exercise 1 of 2

From the REPL to a file

These three lines come from a REPL session, where they printed 42, then 50, then 'NODE'. Saved as main.js, they stop with ReferenceError: _ is not defined, and a file prints nothing it is not told to print anyway. Rewrite main.js so that node main.js prints 42, 50 and NODE, one per line. Keep the calculations: store 6 * 7 in a variable instead of relying on _.

Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.

The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.

Hints
  1. Hint 1

    In a file, a value is printed only when you pass it to console.log.

  2. Hint 2

    _ exists only in the REPL. Give the first result a name: const answer = 6 * 7;

  3. Hint 3

    console.log("node".toUpperCase()) prints NODE without quotes.

Show a solution

One way to solve it. Yours can look different and still pass the checks.

const answer = 6 * 7;
console.log(answer);
console.log(answer + 8);
console.log("node".toUpperCase());
Run it on your computer

Install Node.js 24 LTS or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.

main.js

// Copied from a REPL session. It printed 42, then 50, then 'NODE'.
6 * 7;
_ + 8;
"node".toUpperCase();

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';

test('runs without an error', async () => {
  await runMain();
});

test('prints 42, 50 and NODE, one per line', async () => {
  const got = (await runMain()).trimEnd().split('\n');
  assert.deepEqual(got, ['42', '50', 'NODE'], `the program printed ${JSON.stringify(got)}`);
});

package.json

{
  "type": "module"
}

package.json tells Node.js that the .js files are modules; keep it in the folder.

Run the program:

node main.js

Run the checks (needs learnrun.js in the same folder):

node --test
Download learnrun.js

Exercise 2 of 2

The major version

Write major(version), which takes a version string like "v24.21.0", as process.version gives it, and returns the major version as a number: 24. It must work for any number of digits, such as "v8.17.0" and "v100.0.0". The last line of main.js already prints the running version with it, for example Node.js v24.21.0 major 24. Run it with node main.js and check the tests with node --test.

This exercise needs Node.js on your computer (the browser version cannot run it). The files and commands are below.

Hints
  1. Hint 1

    Remove the leading v first: "v24.21.0".slice(1) is "24.21.0".

  2. Hint 2

    split(".") cuts the rest into ["24", "21", "0"]; the first item is the major version.

  3. Hint 3

    The pieces are strings. Number("24") turns one into the number 24.

Show a solution

One way to solve it. Yours can look different and still pass the checks.

// Returns the major version as a number: "v24.21.0" -> 24.
export function major(version) {
  return Number(version.slice(1).split(".")[0]);
}

console.log("Node.js", process.version, "major", major(process.version));
Run it on your computer

Install Node.js 24 LTS or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.

main.js

// Returns the major version as a number: "v24.21.0" -> 24.
export function major(version) {
  return 0;
}

console.log("Node.js", process.version, "major", major(process.version));

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
import {major} from './main.js';

test('major("v24.21.0") is 24', () => {
  assert.equal(major('v24.21.0'), 24, `major("v24.21.0") returned ${JSON.stringify(major('v24.21.0'))}`);
});

test('works for one-digit and three-digit majors', () => {
  assert.equal(major('v8.17.0'), 8, `major("v8.17.0") returned ${JSON.stringify(major('v8.17.0'))}`);
  assert.equal(major('v100.0.0'), 100, `major("v100.0.0") returned ${JSON.stringify(major('v100.0.0'))}`);
});

test('prints the version of the Node.js that runs it', async () => {
  const expected = `Node.js ${process.version} major ${process.versions.node.split('.')[0]}`;
  const got = (await runMain()).trimEnd();
  assert.equal(got, expected, `the program printed ${JSON.stringify(got)}, expected ${JSON.stringify(expected)}`);
});

package.json

{
  "type": "module"
}

package.json tells Node.js that the .js files are modules; keep it in the folder.

Run the program:

node main.js

Run the checks (needs learnrun.js in the same folder):

node --test
Download learnrun.js

Common mistakes

Pasting a REPL session into a file

> 6 * 7
42

What Node.js prints

SyntaxError: Unexpected token '>'

Why, and the fix

The > at the start of a line is the prompt of the REPL, and the line under it is its answer: neither is JavaScript. Copy only the code you typed, and pass each value you want to see to console.log: console.log(6 * 7). Because this is a SyntaxError, no line of the file runs at all.

Using _ in a file

const total = 6 * 7;
console.log(_ + 1);

What Node.js prints

ReferenceError: _ is not defined

Why, and the fix

_ is a convenience of the REPL, which stores the last result in it. A file has no such variable, so _ is an unknown name there. Name your values instead: console.log(total + 1).

Using fs without importing it

console.log(fs.existsSync("main.js"));

What Node.js prints

ReferenceError: fs is not defined

Why, and the fix

The REPL loads built-in modules such as fs the first time you type their name, so this line works there. A file gets no such help: import what it uses. Put import {existsSync} from "node:fs"; at the top and call existsSync("main.js").

JavaScript in the browser: your browser’s own engine, in a sandboxed worker. Syntax errors are located with acorn 8.18.0, MIT. Licence and source

Exit ticket

5 questions, no hints. Score 80% or more to complete the lesson.

Finish every activity above to unlock the exit ticket.

Report a problem

Spotted something wrong or unclear? Say what, and it will be checked and fixed.

#

At least 20 characters.

Only if you want a reply.

Key ideas

A file, a string or nothing at all

node main.js runs a file. node -e "code" runs a string of JavaScript and prints only what the code logs itself; node -p "code" runs it and also prints the result, so node -p "6 * 7" prints 42. With no file and no flags, node opens the REPL. node --version prints the version that the node command starts, such as v24.21.0; inside a program, process.version holds the same string, and process.versions.node the same without the v. A longer command can live as a "dev" script in package.json, and node --run dev runs it. Put code in double quotes: cmd.exe on Windows does not understand single ones.

The REPL reads, evaluates, prints and loops

The REPL reads a line, evaluates it, prints the result and waits for the next. You need no console.log to see a value: 6 * 7 prints 42, and const price = 4 prints undefined, because a declaration has no value. _ holds the last result, _error the last error. A line that is not finished, such as function double(n) {, makes the REPL wait for more lines. Built-in modules such as fs are loaded the first time you use their name. .help lists the dot commands and .exit leaves; so does Ctrl+D, or Ctrl+C twice on a blank line. Once, Ctrl+C only cancels the current input. None of this help exists in a file.

--watch restarts on every save

node --watch main.js runs main.js, prints Completed running 'main.js'. Waiting for file changes before restarting... and keeps running. When you save main.js or any module it imports, it prints Restarting 'main.js' and runs the program again from the start. A file that no module imports, such as notes.txt, is not watched. --watch-path=src watches the folder src instead, and then imported modules are no longer watched, even with --watch as well. If the new version crashes, watch mode prints the error and waits for the next save. --watch needs a file: it cannot be combined with -e, -p, --check or the REPL. The docs mark watch mode stable since v22.0.0.

Sources

Last reviewed September 30, 2026