Mastering Node.js ES Modules: From CommonJS to Native Imports
This article explains how Node.js 12 introduced native ECMAScript Modules, compares them with CommonJS, shows how to enable the feature, configure package.json, and adapt code using import/export, import.meta, and other module‑specific changes.
In April 2019, the Node.js team released Node.js 12 with native ECMAScript Modules (ESM) support.
ESM is no longer new; tools like Babel and TypeScript have allowed its use for years, but Node.js’s implementation differs significantly from those compile‑time solutions.
Babel/TypeScript Design Philosophy
Babel’s slogan is “Use next generation JavaScript, today,” focusing on compiling new features for current engines. TypeScript’s slogan describes it as a typed superset that compiles to plain JavaScript. Both ultimately produce code limited by the target engine, usually converting ESM to CommonJS for Node.js.
Because Node.js 12 enforces stricter ESM rules, developers need to understand the native implementation before adopting it.
Enabling the Feature
Use the --experimental-modules flag to activate ESM parsing. In this mode, file extensions determine module type:
.mjs – ESM files using import/export.cjs – CommonJS files
.js – Treated as ESM when package.json has
"type": "module"Distinguishing Module Types with package.json
The type field in package.json can be "module" or "commonjs". If omitted, commonjs is assumed. This field affects how .js files are parsed, while .cjs and .mjs are explicit.
{
"type": "module" | "commonjs"
}Depending on the type value, imports are resolved as ESM or CommonJS, allowing seamless inter‑operation.
// package.json "type" is "module"
import './startup/init.js'; // ESM
import 'commonjs-package'; // CommonJS fallback
import './legacy-file.cjs'; // .cjs forces CommonJS
import 'commonjs-package/src/index.mjs'; // .mjs forces ESMKey Differences Between ES Modules and CommonJS
File extensions must be explicit
CommonJS allowed omitting extensions; ESM requires the exact filename, enabling static analysis of dependencies.
Removal of require , exports , module.exports , __filename , __dirname
These CommonJS globals disappear in ESM. Node provides alternatives, such as module.createRequire() for require and the import.meta API for filename and dirname.
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);import.meta
import.metasupplies module‑specific metadata, like its URL.
import.meta is an object exposing context‑specific metadata for a JavaScript module, such as its URL.
console.log(import.meta);
// { url: "file:///home/user/my-module.mjs" }No require.extensions or require.cache
These CommonJS features are unavailable in ESM.
URL‑based file paths
ESM resolves modules using URL semantics, allowing query parameters to affect caching.
import './foo.mjs?query=1'; // loads with query=1
import './foo.mjs?query=2'; // loads with query=2Conclusion
Node.js’s ESM implementation is still experimental (stability level 1) and may evolve, especially regarding inter‑op with CommonJS. Nonetheless, the stricter module system promises better optimization and a unified JavaScript ecosystem across browsers and Node.js.
References
ECMAScript Modules – Node.js official docs
Plan for New Modules Implementation – Node.js roadmap
The new ECMAScript module support in Node.js 12 – 2ality
import.meta – MDN
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Node Underground
No language is immortal—Node.js isn’t either—but thoughtful reflection is priceless. This underground community for Node.js enthusiasts was started by Taobao’s Front‑End Team (FED) to share our original insights and viewpoints from working with Node.js. Follow us. BTW, we’re hiring.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
