What is the difference between CommonJS and ES modules in Node.js?
They are two module systems with different loading semantics, and mixing them is where the pain lives.
- Syntax. CommonJS uses
require()andmodule.exports; ES modules useimportandexport. - Timing.
requireis synchronous and can be called anywhere, including conditionally inside a function.importis static and hoisted — the module graph is resolved before any code runs, which is what makes tree-shaking possible. For a conditional load you need dynamicimport(), which returns a promise. - Bindings. CommonJS gives you a copy of the exported value at the time of the require. ES modules give you a live binding, so if the exporting module reassigns the variable later, importers see the new value.
- Enabling them. Either
"type": "module"in package.json, or the.mjsextension. Under ESM there is no__dirname,__filename, orrequire; the equivalents come fromimport.meta.url.
Note: An ES module can import a CommonJS module, but CommonJS cannot require an ES module — because require is synchronous and ESM resolution is asynchronous. That asymmetry is the single most common migration problem.





