CommonJS vs ES Modules in JavaScript: Key Differences and Usage
CommonJS uses require() and module.exports for synchronous loading, mainly in Node.js, while ES Modules use import and export with asynchronous loading and are standard in modern JavaScript environments. ES Modules support static analysis and tree shaking, making them preferred for frontend and modern backend code.Quick Comparison
Here is a quick side-by-side comparison of CommonJS and ES Modules based on key factors.
| Factor | CommonJS | ES Modules |
|---|---|---|
| Syntax | require() and module.exports | import and export |
| Loading | Synchronous (loads at runtime) | Asynchronous (loads before execution) |
| Environment | Node.js primarily | Browsers and Node.js (modern) |
| Static Analysis | No (dynamic loading) | Yes (static imports allow optimization) |
| Support for Tree Shaking | No | Yes |
| File Extension | .js (usually) | .mjs or .js with type module |
Key Differences
CommonJS modules use require() to load dependencies and module.exports to export functionality. This loading happens synchronously at runtime, which means the code waits for the module to load before continuing. This works well in Node.js where files are local and fast to access.
In contrast, ES Modules use import and export statements that are static and must be declared at the top of the file. This allows JavaScript engines to analyze dependencies before running the code, enabling optimizations like tree shaking (removing unused code). ES Modules load asynchronously, which fits well with browsers and modern JavaScript environments.
Another key difference is compatibility: CommonJS is the older standard mainly for Node.js, while ES Modules are the official JavaScript standard supported in browsers and Node.js (from version 12+ with proper flags or 14+ by default). ES Modules also support features like top-level await and better interoperability with modern tools.
Code Comparison
Here is how you export and import a simple function in CommonJS.
// math.js function add(a, b) { return a + b; } module.exports = { add }; // app.js const math = require('./math'); console.log(math.add(2, 3));
ES Modules Equivalent
The same example using ES Modules syntax looks like this.
// math.mjs export function add(a, b) { return a + b; } // app.mjs import { add } from './math.mjs'; console.log(add(2, 3));
When to Use Which
Choose CommonJS when working on Node.js projects that rely on older packages or tools that do not support ES Modules yet. It is also simpler for quick scripts and server-side code where synchronous loading is acceptable.
Choose ES Modules for modern JavaScript projects, especially frontend code or new Node.js projects, to benefit from static analysis, better optimization, and compatibility with browsers. ES Modules are the future standard and recommended for new codebases.
Key Takeaways
require() and module.exports, mainly in Node.js.import and export with asynchronous loading and support tree shaking.