Last 30 Days
No notifications
Modules let you split code across files and explicitly say what's public. Modern JS uses ES Modules (ESM) with import / export everywhere — browsers, Node, Vite, Next.js. Older Node code uses CommonJS with require / module.exports. This page covers both, named vs default exports, dynamic import(), and how Node + bundlers actually resolve a path like "react".
# Modules
math.js
// named exports — many per file
export const PI = 3.14159;
export function add(a, b) { return a + b; }
export class Vec { /* … */ }// default export — at most one per file
export default function multiply(a, b) { return a * b; }
File: app.js
import multiply, { PI, add } from "./math.js"; // default + named
import { add as plus } from "./math.js"; // rename
import * as math from "./math.js"; // namespace import// index.js
export { add, PI } from "./math.js";
export { default as multiply } from "./math.js";
export * from "./other.js";const mod = await import("./heavy.js");
mod.run();// React.lazy uses this under the hood
const Chart = React.lazy(() => import("./Chart"));
// data.js — works at module top level
const data = await fetch("/api").then(r => r.json());
export default data;| feature | script | module |
| Strict mode | opt-in | always on |
Top-level this | window | undefined |
Top-level var is global | yes | no |
| Each import evaluated once | n/a | yes (cached) |
| HTML script tag | | |
// math.cjs
const PI = 3.14159;
function add(a, b) { return a + b; }module.exports = { PI, add }; // or: exports.add = add
module.exports.default = something; // single default style
// app.cjs
const { PI, add } = require("./math.cjs");
const math = require("./math.cjs");Differences vs ESM:
require is synchronous and runs at call time.require an ESM module synchronously — use await import().import "react")fs, path, http)
2. Relative path? (./foo, ../bar/baz.js)
3. Otherwise look in node_modules/react — read its package.json "main" / "exports" field.import "./util.js" (not ./util)..mjs file is always ESM..cjs file is always CommonJS..js file follows "type" in the nearest package.json ("module" → ESM, "commonjs" or absent → CJS).export default { … huge object … } is opaque to tree-shaking — prefer named exports for libraries.undefined. Restructure or pass dependencies in.utils.js.index.js for public APIs of a folder."type": "module" and use .js everywhere modern.