CommonJS vs es modules in Node.js
Module Systems in Node.js
Node.js supports two module systems: the original CommonJS (CJS) and the modern ES Modules (ESM). Understanding the differences is essential for writing compatible Node.js code.
CommonJS (CJS)
The default module system in Node.js since its inception.
js
// math.js β exporting
function add(a, b) { return a + b; }
module.exports = { add };
// main.js β importing
const { add } = require('./math');
console.log(add(2, 3)); // 5Key characteristics:
- Uses
require()/module.exports - Synchronous loading (blocks until module is loaded)
- Loaded at runtime
- Default in
.jsfiles unless"type": "module"in package.json
ES Modules (ESM)
The official ECMAScript standard, now fully supported in Node.js 12+.
js
// math.mjs β exporting
export function add(a, b) { return a + b; }
// main.mjs β importing
import { add } from './math.mjs';
console.log(add(2, 3)); // 5Key characteristics:
- Uses
import/exportsyntax - Asynchronous loading (better for tree-shaking)
- Statically analyzed at parse time
- Use
.mjsextension OR set"type": "module"in package.json
Comparison Table
| Feature | CommonJS | ES Modules |
|---|---|---|
| Syntax | require() / module.exports | import / export |
| Loading | Synchronous | Asynchronous |
| Analysis | Runtime | Static (parse time) |
| Tree-shaking | β | β |
Top-level await | β | β |
__dirname / __filename | β | β (use import.meta.url) |
| Default in Node.js | β | With "type":"module" |
Interoperability
js
// ESM can import CJS:
import { add } from './math.cjs'; // β
// CJS cannot require() ESM:
const { add } = require('./math.mjs'); // β Error!
// CJS can use dynamic import() for ESM:
const { add } = await import('./math.mjs'); // β
Enabling ESM
Option 1: Use .mjs extension
Option 2: Add to package.json:
json
{
"type": "module"
}Getting __dirname in ESM
js
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);Summary
Use ESM for new projects (it's the standard, supports tree-shaking and top-level await). Use CommonJS when working with legacy code or packages that don't support ESM yet.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.