What do you think of CommonJS vs ESM?
TL;DR
JavaScript has evolved its module systems. ESM (ECMAScript Modules) using import
/ export
is the official standard, natively supported in modern browsers and Node.js, designed for both synchronous and asynchronous use cases. CommonJS (CJS) using require
/ module.exports
was the original standard for Node.js, primarily synchronous, and remains prevalent in the Node ecosystem. AMD (Asynchronous Module Definition) using define
/ require
was an early system designed for asynchronous loading in browsers but is now largely obsolete, replaced by ESM.
Overview
Module systems help manage this complexity by allowing code to be split into reusable pieces (modules) with clear dependencies. Over time, different module systems emerged before an official standard was adopted.
CommonJS
Characteristics
- Designed for synchronous loading of modules
- Primarily used in server-side environments like Node.js
- Uses
module.exports
andrequire
for defining and loading modules
Example
// Defining a module in CommonJS
const dep1 = require('dependency1');
const dep2 = require('dependency2');
module.exports = {
// Module code here
};
// Loading a module in CommonJS
const mod1 = require('module1');
const mod2 = require('module2');
// Code that uses mod1 and mod2
ESM (ECMAScript Modules)
Characteristics
- Official JavaScript standard module system
- Supported natively in modern browsers and Node.js
- Designed for both asynchronous and synchronous scenarios
- Uses
export
andimport
for defining and loading modules
Example
import dep1 from 'dependency1'; // if dependency1 had a default export
import { dep2 } from 'dependency2'; // named import to import something specific from dependency2
// Module code using dep1, dep2...
export function someFunction() {
// ... function logic ...
}
export const someValue = 'hello';
// Or export multiple things at once
// export { someFunction, someValue };
// Or export a default value
// export default class MyClass {
// ...
// }
Key differences
Loading mechanism
- CommonJS: Synchronous (blocks until loaded).
- ESM: Asynchronous-friendly (non-blocking in browsers).
Environment suitability
- CommonJS: Node.js legacy standard.
- ESM: Official standard (Browser & Node.js).
Syntax
- CommonJS:
require()
/module.exports
. - ESM:
import
/export
.
Analysis
- CommonJS: Dynamic (runtime analysis).
- ESM: Static (compile-time analysis, enables tree-shaking).
Use cases
CommonJS
- Older Node.js projects or where sync loading is needed.
- Default in Node.js unless configured for ESM.
ESM
- Modern web development (native browser support).
- New Node.js projects, especially those needing async features or optimizations.
- Code intended for both browser and server.