Historically, Node.js relied exclusively on the CommonJS module system (require and module.exports). However, as JavaScript evolved, a newer, standardized module system was introduced to the web browser: ES Modules (or ECMAScript Modules).
Today, Node.js fully supports ES Modules natively. This allows you to write back-end JavaScript code using the exact same import and export syntax that you use in front-end frameworks like React, Vue, or vanilla browser JavaScript!
By default, Node.js still treats .js files as CommonJS modules. To start using ES Modules in your project, you have two primary options:
.mjs ExtensionYou can change the file extension of your JavaScript files from .js to .mjs. Node.js will automatically treat any .mjs file as an ES Module.
package.json (Recommended)If you want your entire project to use ES Modules by default, you can add a specific property to your project's package.json file:
{
"name": "my-node-app",
"type": "module"
}
Once "type": "module" is set, all .js files in your project are parsed as ES Modules.
Unlike CommonJS which uses module.exports, ES Modules use the export keyword. You can export items in two ways: Named Exports and Default Exports.
You can export multiple variables or functions from a single file by placing the export keyword in front of them.
// Exporting individually export const pi = 3.14159;export function calculateArea(radius) { return pi * radius * radius; }
A file can have a maximum of one default export. This is typically used when a module only has one primary function or class to share.
function logMessage(msg) {
console.log(`[LOG]: ${msg}`);
}
// Exporting as default
export default logMessage;
To bring exported code into another file, you use the import keyword.
Important Note: When using ES Modules in Node.js, you must include the .js file extension in your import path for local files!
// 1. Importing Named Exports (must use curly braces and exact names)
import { pi, calculateArea } from './utils.js';
// 2. Importing a Default Export (no curly braces, name it whatever you want)
import myLogger from './logger.js';
// 3. Importing a Built-in Core Module (no relative path needed)
import fs from 'fs';
myLogger("Starting application...");
console.log("Area of circle with radius 5:", calculateArea(5));
Here is a quick cheat sheet to help you remember the differences:
| Feature | CommonJS (Legacy/Default) | ES Modules (Modern Standard) |
|---|---|---|
| Syntax | require() |
import |
| Exporting | module.exports = ... |
export default ... |
| Extensions | Optional when importing | Required when importing local files |
| Synchronous? | Yes, loads synchronously | No, loads asynchronously |
Pro Tip: ES Modules are the future of JavaScript. Unless you are working on a legacy codebase, it is highly recommended to build new Node.js applications using ES Modules to keep your code aligned with modern web standards.
How do you tell Node.js to treat all `.js` files in a project as ES Modules?