Hint
ESM: static import/export, live bindings, always strict; CJS: require(), dynamic, copied values
// ── ES Modules (ESM) ─────────────────────────────
// math.js
export const PI = 3.14;
export function add(a, b) { return a + b; }
export default class App {}
// main.js
import { PI, add } from './math.js'; // named imports
import App from './App.js'; // default import
import * as Math from './math.js'; // namespace
// ── CommonJS (CJS) ─────────────────────────────
module.exports = { PI, add };
const { PI, add } = require('./math');
// ── Key Differences ────────────────────────────
| Feature | ESM | CommonJS |
|---|---|---|
| Analysis | Static (parse time) | Dynamic (runtime) |
| Binding | Live (tracks changes) | Copied (snapshot) |
| Strict mode | Always | Opt-in |
| Top-level await | ✅ | ❌ |
| Browser | type="module" | Bundler needed |
| Tree shaking | ✅ (static) | ❌ (dynamic) |