On this page
Node.js Modules
Node.js organizes code into modules — each file is a separate module with its own scope.
CommonJS (Default in Node.js)
Exporting
// math.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
module.exports = { add, subtract };
// Or export individually
exports.multiply = (a, b) => a * b;
Importing
// app.js
const { add, subtract } = require('./math');
const math = require('./math');
console.log(add(2, 3)); // 5
console.log(math.subtract(5, 2)); // 3
ES Modules
Enable with "type": "module" in package.json or use .mjs extension.
// math.js
export function add(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
// app.js
import multiply, { add } from './math.js';
console.log(add(2, 3));
console.log(multiply(2, 3));
Note: ES modules require file extensions in import paths: './math.js'.
Built-in Modules
Node.js includes core modules — no installation needed:
const fs = require('fs'); // File system
const path = require('path'); // Path utilities
const http = require('http'); // HTTP server/client
const os = require('os'); // OS information
const crypto = require('crypto'); // Cryptography
const events = require('events'); // EventEmitter
Or with ES modules:
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
__dirname and __filename
In CommonJS:
console.log(__filename); // full path to current file
console.log(__dirname); // directory of current file
In ES modules, derive them manually (see example above).
Module Caching
Modules are cached after first load — subsequent require() returns the cached exports:
// counter.js
let count = 0;
module.exports = {
increment: () => ++count,
getCount: () => count
};
// app.js
const c1 = require('./counter');
const c2 = require('./counter');
c1.increment();
console.log(c2.getCount()); // 1 — same instance
Circular Dependencies
Avoid circular imports when possible. Node.js handles them but may return partially initialized exports.
Best Practices
- One module = one responsibility
- Use ES modules for new projects
- Prefer named exports for clarity
- Keep
index.jsas a barrel file re-exporting from a folder