Node.js lets you run JavaScript outside the browser: web servers, command-line tools, automation scripts. It combines:
- V8, Chrome’s JavaScript engine, which runs your code;
- libuv, a library that handles I/O (files, network, timers) asynchronously;
- a standard library of modules (
node:fs,node:http,node:crypto…).
Your code runs on a single thread. Slow operations (reading a file, waiting for a request) are handed off to the system; Node keeps processing other tasks and resumes your code when the result arrives. This is the event loop, which we will cover in detail later. An important consequence: a long synchronous computation blocks the entire server.
Compared to the browser: no window, no document, no DOM. On the other hand, globalThis, console, setTimeout, fetch, URL, and structuredClone are available. In production, use an LTS version (even-numbered): Node 26 is the current LTS.
Running code
node --version # v26.x (current LTS)
node # REPL: interactive console (.exit to quit)
node script.js # run a file
node --watch server.js # restart automatically on every change
node --env-file=.env app.js # load a .env file (stable option)
node outil.ts # run TypeScript: types are stripped, not checked
The process object
process is a global object that represents the running program.
// node saluer.js Ada --majuscules
console.log(process.argv);
// [ '/usr/bin/node', '/home/ada/saluer.js', 'Ada', '--majuscules' ]
console.log(process.platform, process.version, process.cwd());
The first two elements of process.argv are the path to Node and the path to the script. To parse options, util.parseArgs (stable since Node 20) saves you from coding everything by hand:
const { parseArgs } = require("node:util");
const { values, positionals } = parseArgs({
args: process.argv.slice(2),
options: {
port: { type: "string", short: "p", default: "3000" },
verbose: { type: "boolean", short: "v", default: false },
},
allowPositionals: true,
});
// node serve.js -p 8080 -v public => values.port === "8080", positionals = ["public"]
Environment variables
Configuration (port, database URL, API keys) is read from process.env. It is not in the code: this way the same program can be used in development and in production.
const config = {
port: Number(process.env.PORT ?? 3000), // values are ALWAYS strings
nodeEnv: process.env.NODE_ENV ?? "development",
databaseUrl: process.env.DATABASE_URL,
};
if (!config.databaseUrl) {
console.error("DATABASE_URL is missing");
process.exit(1); // fail early and clearly
}
Validate the configuration at startup: it is better to refuse to start than to fail in the middle of the night on the first request.
Exit codes
A program that ends returns an exit code: 0 for success, anything else for an error. Shell scripts, CI, and Docker rely on it. Prefer process.exitCode = 1 (the program cleanly finishes its pending tasks) to process.exit(1) (immediate stop), except at startup.
Key takeaways
Node = V8 + libuv + standard library, on a non-blocking thread. process.argv and util.parseArgs for arguments, process.env (strings) for configuration, and an exit code to communicate the result.
Exercises
Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.
Parse arguments with util.parseArgs
Write
parseCliArgs(args)(an array of arguments, without the first two elements ofprocess.argv) usingutil.parseArgs:- option
--port/-p(string, default"3000"), returned as a number; - option
--verbose/-v(boolean, defaultfalse); - positional arguments returned in
files.
Return
{ port, verbose, files }.const { parseArgs } = require("node:util"); function parseCliArgs(args) { // À compléter }- option
Load a validated configuration
Write
loadConfig(env)(an object likeprocess.env) that returns a frozen object (Object.freeze):port:env.PORTconverted to an integer, 3000 by default; throw anErrorif it is not an integer between 1 and 65535;nodeEnv:env.NODE_ENVor"development";databaseUrl:env.DATABASE_URL, required (otherwise anErrorwhose message containsDATABASE_URL).
function loadConfig(env) { // À compléter }Understand Node's model
A route in your Node server runs a synchronous loop for 5 seconds. What happens to the other users?
- Nothing, each request has its own thread
- Their requests wait: the event loop is blocked
- Node automatically spawns a new process
End-of-lesson quiz
What does
process.argv[2]contain fornode app.js --port 80?- node
- app.js
- --port
What type are the values of
process.env?- Their original type (number, boolean)
- Always strings (or undefined)
- JSON objects
Which exit code signals success?
- 0
- 1
- 200
The rest of the course
- CommonJS, ES Modules, and npm18 min
- Async: Callbacks, Promises, and the Event Loop20 min
- Files and Paths: node:fs and node:path18 min
- Events, Streams, and the Native HTTP Server20 min