Lesson 3 of 20

Node.js Modules

CommonJS Modules (require / module.exports)

Node.js uses a module system to organize code into separate files. The traditional module system is CommonJS, which uses require() to import and module.exports to export. Each file in Node.js is treated as a separate module with its own scope.

When you require a module, Node.js looks for it in three places: built-in modules (like fs, path), node_modules folder (installed packages), and local files (using relative paths like ./myModule).

Example
// math.js — Exporting a module
function add(a, b) {
  return a + b;
}

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

module.exports = { add, multiply };

// app.js — Importing the module
const { add, multiply } = require('./math');

console.log(add(5, 3));       // 8
console.log(multiply(4, 2));  // 8

// You can also export a single value
// module.exports = function greet(name) {
//   return `Hello, ${name}!`;
// };
  • require() — Import modules, packages, or local files
  • module.exports — Export values from a module
  • exports.name — Shorthand for adding properties to module.exports
  • Each file is a module — Variables are scoped to the file, not global
  • Modules are cached — require() only runs the file once, then caches the result
Notes
  • Always use relative paths (./file) for local modules. Without the ./ prefix, Node.js looks for built-in or node_modules packages.

ES Modules (import / export)

Modern Node.js also supports ES Modules (ESM), the same import/export syntax used in frontend JavaScript. To use ES modules, either set "type": "module" in your package.json or use the .mjs file extension.

ES Modules are the future of JavaScript modules. They support top-level await, static analysis, and tree-shaking. However, many existing npm packages still use CommonJS, so understanding both systems is important.

Example
// First, add to package.json: "type": "module"

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

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

// app.mjs — Importing named exports
import { add, multiply } from './math.mjs';

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

// Default export
export default class Calculator {
  add(a, b) { return a + b; }
}

// Importing default export
import Calculator from './Calculator.mjs';
  • import / export — Modern ES Module syntax
  • "type": "module" — Add to package.json to enable ESM in .js files
  • .mjs extension — Use ES Modules without changing package.json
  • Named exports — Export multiple values by name
  • Default export — Export a single main value from a module
Notes
  • You cannot mix require() and import in the same file. Choose one module system per file.

Built-in Modules

Node.js comes with many built-in modules that provide essential functionality without installing any packages. These modules cover file system operations, networking, cryptography, and more.

You can import built-in modules using just their name — no file path or installation needed.

Example
// Common built-in modules
const fs = require('fs');           // File system operations
const path = require('path');       // File path utilities
const http = require('http');       // HTTP server and client
const os = require('os');           // Operating system info
const crypto = require('crypto');   // Cryptographic functions
const url = require('url');         // URL parsing
const events = require('events');   // Event emitter

// Example: Generate a random ID
const id = crypto.randomUUID();
console.log('Random ID:', id);
// Random ID: 550e8400-e29b-41d4-a716-446655440000

// Example: Get system info
console.log('Home Directory:', os.homedir());
console.log('Hostname:', os.hostname());
Notes
  • In modern Node.js, you can use the 'node:' prefix for built-in modules: require('node:fs'). This makes it clear you are importing a built-in module.