Node.js: The Runtime, process, and Configuration

First lesson of the Node.js Fundamentals course, free to read: about 15 minutes, 3 exercises and 3 quiz questions. This is the catalogue's base lesson; in the student space, it is rewritten for your profile.

Objectives

  • Explain what Node.js is and how it differs from browser JavaScript
  • Run a script and read its arguments and environment variables
  • Build a validated configuration from process.env

Node.js runtimeThe process objectConfiguration through the environment

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.

  1. CodeDifficulty 2JavaScript in the browser2 hints

    Parse arguments with util.parseArgs

    Write parseCliArgs(args) (an array of arguments, without the first two elements of process.argv) using util.parseArgs:

    • option --port / -p (string, default "3000"), returned as a number;
    • option --verbose / -v (boolean, default false);
    • positional arguments returned in files.

    Return { port, verbose, files }.

    const { parseArgs } = require("node:util");
    
    function parseCliArgs(args) {
      // À compléter
    }
  2. CodeDifficulty 2JavaScript in the browser1 hint

    Load a validated configuration

    Write loadConfig(env) (an object like process.env) that returns a frozen object (Object.freeze):

    • port: env.PORT converted to an integer, 3000 by default; throw an Error if it is not an integer between 1 and 65535;
    • nodeEnv: env.NODE_ENV or "development";
    • databaseUrl: env.DATABASE_URL, required (otherwise an Error whose message contains DATABASE_URL).
    function loadConfig(env) {
      // À compléter
    }
  3. Multiple choiceDifficulty 11 hint

    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

  1. What does process.argv[2] contain for node app.js --port 80?

    • node
    • app.js
    • --port
  2. What type are the values of process.env?

    • Their original type (number, boolean)
    • Always strings (or undefined)
    • JSON objects
  3. Which exit code signals success?

    • 0
    • 1
    • 200

The rest of the course

  1. CommonJS, ES Modules, and npm18 min
  2. Async: Callbacks, Promises, and the Event Loop20 min
  3. Files and Paths: node:fs and node:path18 min
  4. Events, Streams, and the Native HTTP Server20 min

Node.js Fundamentals · Intermediate · 3 h 1 min