In a Node.js project, you're likely to run into both CommonJS and ESM modules. Here's how to tell these module types apart at a glance.
CommonJS
CommonJS modules were part of Node.js when it was written in 2009. They run synchronously. Imports and exports are resolved and scripts are executed dynamically at runtime.
CommonJS uses __filename
, __dirname
, and NODE_PATH
variables. ESM does not.
ESM
ECMAScript modules (ESM) or ES Modules were introduced in 2015 with JavaScriptES6 (also known as ECMAScript 2015 or ECMAScript 6). They are asynchronous. Imports and exports are resolved statically at parse time. The ESM module loader then downloads and parses scripts. Finally, the script executes.
ESM uses top-level await
(await
in a file outside an async function()
). CommonJS does not.
Package.json
CommonJS:
"type": "commonjs"
ESM:
"type": "module"
Node.js throws an error for ESM modules without "type": "module"
, but I have yet to see a package.json
with "type": "commonjs"
in the wild.
Imports
CommonJS:
var module = require('file path');
ESM:
import defaultStuff, { namedStuff } from 'file path';
Exports
CommonJS:
// default
module.exports =
// default read-only
exports =
// named
module.exports.name =
// named read-only
exports.name =
ESM:
// default
export default name
// named
export name
File Extensions
Node.js will treat .js
and .ts
as CommonJS modules by default.
CommonJS uses .cjs
for JavaScript and .cts
for TypeScript.
ESM uses .mjs
for JavaScript and .mts
for TypeScript.
Runtime Environments
CommonJS is supported in all versions of Node.js.
ESM is supported in browsers and Node.js v12 or higher.
Strict Mode
CommonJS needs use strict
at the top of the file.
ESM uses strict mode by default.
This
In CommonJS modules, this
points at exports
.
In ES modules, this
is undefined
.
Conclusion
At this point, I've upgraded a package and gotten an error like "ES Modules not supported" or "[module] is a CommonJS module, which may not support all module.exports as named exports" a few times. While troubleshooting, the search results I got were guides on how to write these modules or treatises on which one is better. This is the summary I wish I had before I had to jump down a rabbit hole just to understand an error.
Top comments (3)
I've been struggling with all of this lately. My take is:nowadays prefer always ESM modules, CommonJs was a temporal best effort till official module system were a thing. Now, just use ESM modules :)
Common Js is slowly retiring.
Thanks for the post ^^
for deeper analysis of pros and cons of each module system I suggest this post too:
webreflection.medium.com/cjs-vs-es...
Some comments have been hidden by the post's author - find out more