Débutant20 min de lecture

Modules & require

Learn how Node.js organizes code into modules, use require/exports, and understand the module system.

Why Modules?

Imagine writing an entire web application in a single file — thousands of lines of code for authentication, database queries, API routes, email sending, payment processing, and utility functions, all mixed together. Finding a bug would be like searching for a specific grain of sand on a beach. Changing one thing could break something completely unrelated. This is why every serious programming language has a module system.

Modules let you split your code into separate files, each responsible for one specific thing. A database.js module handles database connections. An auth.js module handles login and registration. A utils.js module has helper functions. Each module is a self-contained unit with its own scope — variables defined inside a module do not leak into other modules.

The benefits of using modules are significant:

  • Reusability — Write a function once and use it across your entire project by importing it wherever needed. If you write a formatDate() function, every file that needs date formatting can import it.
  • Maintainability — When something breaks, you know exactly which file to look at. Fixing a bug in the payment module does not require reading the email module.
  • Encapsulation — Each module can keep internal details private and only expose what other modules need. Your database module might have 20 internal helper functions but only export 5 public ones.
  • No naming conflicts — Two modules can both define a variable called count without interfering with each other. Each module has its own scope.
  • Team collaboration — Different team members can work on different modules simultaneously without stepping on each other's code.

Node.js was built with modules in mind from the very beginning. Every .js file in Node.js is automatically treated as a separate module.

CommonJS Modules (require / module.exports)

Node.js originally used (and still supports) the CommonJS module system. This is the require() and module.exports pattern you will see in much of the existing Node.js code online.

Exporting from a module — Use module.exports to make things available to other files:

javascript
// math.js
function add(a, b) {
  return a + b;
}

function multiply(a, b) {
  return a * b;
}

module.exports = { add, multiply };

You can also export a single value:

javascript
// greet.js
module.exports = function(name) {
  return "Hello, " + name + "!";
};

Importing a module — Use require() to load a module:

javascript
// app.js
const math = require('./math');        // Import our math module
const greet = require('./greet');      // Import our greet module

console.log(math.add(5, 3));           // 8
console.log(math.multiply(4, 7));      // 28
console.log(greet('Alice'));           // Hello, Alice!

Notice the ./ before the file name — this tells Node.js to look for a local file relative to the current file. Without ./, Node.js would look for a built-in module or an installed npm package instead.

Each file gets its own scope automatically. If math.js defines a variable called secretKey, it is invisible to app.js unless explicitly exported. This is a key difference from browser JavaScript, where all scripts loaded via <script> tags share the same global scope and can accidentally overwrite each other's variables.

ES Modules (import / export)

ES Modules (ESM) are the modern, standardized JavaScript module system. They use the import and export keywords that you may have already seen in frontend frameworks like React. Node.js has supported ES Modules since version 12, and they are now the recommended approach for new projects.

To use ES Modules in Node.js, you need to either:

  • Set "type": "module" in your package.json file, OR
  • Use the .mjs file extension instead of .js

Named exports — Export multiple things by name:

javascript
// math.mjs
export function add(a, b) {
  return a + b;
}

export function multiply(a, b) {
  return a * b;
}

export const PI = 3.14159;

Importing named exports:

javascript
// app.mjs
import { add, multiply, PI } from './math.mjs';

console.log(add(5, 3));      // 8
console.log(PI);             // 3.14159

Default export — Export one main thing from a module:

javascript
// greet.mjs
export default function(name) {
  return "Hello, " + name + "!";
}
javascript
import greet from './greet.mjs';
console.log(greet('Alice'));  // Hello, Alice!

The key differences from CommonJS: import/export are static — they must be at the top level of the file (not inside an if block or a function). This allows tools to analyze your code and optimize it (called tree-shaking — removing unused exports). Most modern projects, including Next.js and React apps, use ES Modules. You will encounter both systems in the real world, so knowing both is important.

Module Systems Side by Side

html
<div style="font-family:sans-serif; padding:16px;">
  <h3>CommonJS vs ES Modules</h3>
  <div style="display:flex; gap:16px; flex-wrap:wrap;">
    <!-- CommonJS -->
    <div style="flex:1; min-width:280px; border:2px solid #3b82f6; border-radius:8px; overflow:hidden;">
      <div style="background:#3b82f6; color:white; padding:8px 12px; font-weight:bold;">CommonJS (require)</div>
      <pre style="padding:12px; margin:0; font-size:13px; background:#f8fafc; overflow-x:auto;">// utils.js
function formatDate(date) {
  return date.toLocaleDateString();
}

function capitalize(str) {
  return str[0].toUpperCase() + str.slice(1);
}

module.exports = { formatDate, capitalize };

// app.js
const { formatDate, capitalize } = require('./utils');

console.log(capitalize('hello'));  // Hello
console.log(formatDate(new Date())); </pre>
    </div>
    <!-- ES Modules -->
    <div style="flex:1; min-width:280px; border:2px solid #10b981; border-radius:8px; overflow:hidden;">
      <div style="background:#10b981; color:white; padding:8px 12px; font-weight:bold;">ES Modules (import/export)</div>
      <pre style="padding:12px; margin:0; font-size:13px; background:#f8fafc; overflow-x:auto;">// utils.mjs
export function formatDate(date) {
  return date.toLocaleDateString();
}

export function capitalize(str) {
  return str[0].toUpperCase() + str.slice(1);
}

// app.mjs
import { formatDate, capitalize } from './utils.mjs';

console.log(capitalize('hello'));  // Hello
console.log(formatDate(new Date()));</pre>
    </div>
  </div>
</div>

Built-in Modules

Node.js comes with a rich set of built-in modules that you can use without installing anything. These are part of Node.js itself and provide core functionality that backend applications need:

fs (File System) — Read, write, create, and delete files and directories on the computer:

javascript
const fs = require('fs');
const data = fs.readFileSync('config.json', 'utf8');
fs.writeFileSync('output.txt', 'Hello World');

path — Work with file and directory paths in a cross-platform way:

javascript
const path = require('path');
const fullPath = path.join(__dirname, 'data', 'users.json');
const ext = path.extname('photo.jpg'); // '.jpg'

http — Create web servers and make HTTP requests:

javascript
const http = require('http');
const server = http.createServer((req, res) => {
  res.end('Hello World');
});
server.listen(3000);

crypto — Cryptographic functions for hashing, encryption, and generating secure random values:

javascript
const crypto = require('crypto');
const hash = crypto.createHash('sha256').update('password').digest('hex');

os — Get operating system information:

javascript
const os = require('os');
console.log(os.hostname());  // Your computer's name
console.log(os.cpus().length); // Number of CPU cores

url — Parse and construct URLs. events — Create event emitters. stream — Handle streaming data. child_process — Run shell commands from Node.js.

You require built-in modules by name (no ./ prefix). When Node.js sees require('fs'), it knows to load the built-in file system module rather than looking for a local file called fs.js.

What function is used to import a module in CommonJS?

Prêt à pratiquer ?

Crée ton compte gratuit pour accéder à l'éditeur de code interactif, lancer les défis et suivre ta progression.