Using CommonJS and ES Modules Together in Node.js
In its early versions, Node.js only used the CommonJS module system (require and module.exports). However, over time Node.js began supporting ES Modules (import and export) as well, giving developers more flexibility.
Today it's possible to use both systems, but there are some important nuances when combining them.
How to Use ES Modules in Node.js
For Node.js to recognize your file as an ES Module, you need to do one of the following:
- Use the .mjs file extension (e.g.,
index.mjs) - Or add the
"type": "module"field in your package.json file:
{
"type": "module"
}
Then all .js files will be treated as ES Modules.
Importing CommonJS from ES Modules
If you have a CommonJS module and want to use it from ES Modules, you need to use a special import format. For example:
// greet.cjs file (CommonJS)
module.exports = function(name) {
return `Hello, ${name}!`;
};
// main.mjs file (ES Module)
import greet from './greet.cjs';
console.log(greet('Ani')); // Hello, Ani!
Node.js will automatically convert the CommonJS module to behave like a default export so it can be imported.
Importing ES Modules from CommonJS
If you want to use an ES Module in CommonJS code, it's a bit more complicated. You can't directly require() an ES Module. In this case, you need to use the dynamic import() function which returns a Promise.
// greet.mjs file (ES Module)
export function greet(name) {
return `Hello, ${name}!`;
}
// main.cjs file (CommonJS)
async function loadGreet() {
const { greet } = await import('./greet.mjs');
console.log(greet('Ani')); // Hello, Ani!
}
loadGreet();
This approach requires async functions since the import() function returns a Promise.
Key Differences in Node.js
- CommonJS imports are synchronous, while ES Module imports are asynchronous
- In CommonJS you can dynamically determine which module to import at runtime, while ES Modules require import statements at the top of files
- CommonJS modules are cached immediately after require
- ES Modules work better with modern tools and optimizations (like tree-shaking)
Conclusion
Node.js now supports both CommonJS and ES Modules, but when combining them it's important to understand the syntactic and technical differences. For new projects, it's recommended to prefer ES Modules when possible, as they align with modern JavaScript standards and provide better compatibility with advanced tools.