Node.js ES Modules
ES Modules (ESM) are the official JavaScript way to share code between files. Browsers and Node.js both support them. You write import and export instead of require and module.exports.
Why Learn ES Modules
Modern libraries and tutorials use ESM. The syntax reads clearly and works the same in the browser and on the server. Learning it prepares you for current projects.
Two Module Styles in Node.js
+------------------------+--------------------------+
| CommonJS (older) | ES Modules (modern) |
+------------------------+--------------------------+
| require("fs") | import fs from "fs" |
| module.exports = x | export default x |
| File type: .js | File type: .mjs or .js |
+------------------------+--------------------------+
Turn On ES Modules
Node.js needs a signal that your file uses ESM. Pick one of two options.
Option 1: Use the .mjs Extension
Name your file app.mjs. Node.js treats it as an ES module.
Option 2: Set the Type in package.json
Add one line to your package.json file. Every .js file in the project then uses ESM.
{
"name": "my-app",
"type": "module"
}Export Code
Named Exports
Named exports share several items from one file. Each item keeps its own name.
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}Default Export
A default export shares one main item. Each file holds at most one default export.
// greet.js
export default function greet(name) {
return "Hello, " + name;
}Import Code
Import Named Items
Wrap named items in curly braces. The names must match the export names.
// app.js
import { add, multiply, PI } from "./math.js";
console.log(add(2, 3)); // 5
console.log(multiply(4, 5)); // 20
console.log(PI); // 3.14159Import a Default Item
Skip the curly braces for a default export. You choose any local name.
import greet from "./greet.js";
console.log(greet("Asha"));Rename an Import
import { add as sum } from "./math.js";
console.log(sum(10, 20));Import Everything
import * as math from "./math.js";
console.log(math.add(1, 2));How Files Connect
math.js greet.js
export add export default greet
export multiply |
export PI |
| |
+-----------+------------+
|
v
app.js
import { add } from "./math.js"
import greet from "./greet.js"
Rules to Remember
- Write the full file extension in local imports, such as ./math.js.
- Place import statements at the top level of the file.
- Use the node: prefix for core modules, such as import fs from "node:fs".
- Expect strict mode to run automatically in every ES module.
Replace __dirname in ESM
ES modules do not provide __dirname or __filename. Build them from import.meta.url.
import { fileURLToPath } from "node:url";
import path from "node:path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
console.log(__dirname);Top-Level Await
ES modules allow await outside a function. This feature keeps small scripts short.
const response = await fetch("https://example.com/data.json");
const data = await response.json();
console.log(data);Common Errors
Cannot use import statement outside a module
Node.js treats your file as CommonJS. Rename the file to .mjs or add the type setting to package.json.
require is not defined
ESM files do not support require. Switch to import for the same task.
Practice Tasks
- Create a file with three math functions and export them by name.
- Import two of them into another file and print the results.
- Add a default export that returns a welcome message.
