Splitting code into modules
A real application does not fit in a single file. Node lets you separate code into modules (files) that export and import functionality. There are two systems that will coexist for a long time.
CommonJS (Node's classic)
Uses require to import and module.exports to export:
// math.js
function add(a, b) { return a + b; }
module.exports = { add };
// app.js
const { add } = require("./math");
console.log(add(2, 3)); // 5
ES Modules (the modern standard)
It is the language's standard syntax, the same as in the browser. It uses
import / export:
// math.js
export function add(a, b) { return a + b; }
// app.js
import { add } from "./math.js";
To use ESM in Node you set "type": "module" in the package.json (or you use
the .mjs extension). Key differences: require is synchronous and dynamic
(you can call it inside an if); import is static (resolved before
running) and allows optimizations.
package.json and npm
The package.json is the project's manifest: name, version, scripts and
dependencies. With npm (Node's package manager) you install libraries:
{
"name": "my-app",
"type": "module",
"scripts": { "start": "node app.js" },
"dependencies": { "express": "^4.18.0" }
}
npm install express downloads the package to node_modules and records it in
dependencies. Then you import it by its name: import express from "express".
The standard library
Node ships with built-in modules (no need to install them):
fs: read and write files (file system).path: build paths portably across operating systems.os: system information (CPUs, memory...).http: create HTTP servers and clients.process.env: read environment variables (configuration and secrets).
Examples
Import a module from the standard library (CommonJS)
const path = require("path");
console.log(path.join("folder", "file.txt")); // "folder/file.txt"
console.log(path.extname("photo.png")); // ".png"