Modules
Split code into files. Import what you need, export what others can use.
Named Exports
Export multiple values from a module by name.
// math.js — export individually:
export const PI = 3.14159;
export const E = 2.71828;
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// Or export all at once at the bottom:
const PI = 3.14159;
const E = 2.71828;
function add(a, b) { return a + b; }
function multiply(a, b) { return a * b; }
export { PI, E, add, multiply };
// Rename on export:
export { add as sum, multiply as product };// Importing named exports:
import { PI, add } from "./math.js";
console.log(PI); // 3.14159
console.log(add(2, 3)); // 5
// Rename on import:
import { add as sum } from "./math.js";
sum(2, 3); // 5
// Import everything as a namespace:
import * as math from "./math.js";
math.PI; // 3.14159
math.add(2, 3); // 5Default Exports
One main export per module — imported without braces.
// User.js — one default export per file:
export default class User {
constructor(name) {
this.name = name;
}
}
// Or export separately:
class User { /* ... */ }
export default User;
// Functions:
export default function fetchData(url) {
return fetch(url).then(r => r.json());
}
// Even expressions:
export default [1, 2, 3];// Importing defaults — no braces, any name works:
import User from "./User.js"; // ✓
import MyUser from "./User.js"; // ✓ same thing, different name
import Whatever from "./User.js"; // ✓ name doesn't matter
// Combine default + named:
import React, { useState, useEffect } from "react";
import axios, { AxiosError } from "axios";
// ⚠️ Only ONE default per module:
export default class A {}
export default class B {} // ❌ SyntaxErrorNamed exports
Multiple per file
Must use exact name
Better for utilities
Default export
One per file
Any import name
Better for components
Import Patterns
All the ways to import modules.
// Named import:
import { useState, useEffect } from "react";
// Default import:
import React from "react";
// Both:
import React, { useState } from "react";
// Namespace (all as object):
import * as utils from "./utils.js";
// Rename:
import { render as renderDOM } from "react-dom";
// Side-effect only (no values imported):
import "./styles.css";
import "./polyfills.js";
// Re-export (barrel files):
// index.js
export { Button } from "./Button.js";
export { Input } from "./Input.js";
export { Modal } from "./Modal.js";
// Now consumers: import { Button, Input, Modal } from "./components";
// Re-export everything:
export * from "./math.js";
export { default } from "./User.js";Dynamic Imports
Load modules on demand — code splitting.
// import() returns a Promise:
const module = await import("./heavy-module.js");
module.doSomething();
// Conditional loading:
if (user.isAdmin) {
const { AdminPanel } = await import("./AdminPanel.js");
renderAdmin(AdminPanel);
}
// Lazy load on event:
button.addEventListener("click", async () => {
const { openModal } = await import("./modal.js");
openModal();
});Dynamic import() loads modules at runtime. The browser downloads the code only when the import is executed — perfect for code splitting.
Module Patterns
Common conventions and best practices.
// 1. Barrel file (re-export pattern):
// components/index.js
export { Button } from "./Button";
export { Input } from "./Input";
export { Card } from "./Card";
// Import: import { Button, Input, Card } from "./components";
// 2. Module-level state (singleton):
// counter.js
let count = 0;
export const increment = () => ++count;
export const getCount = () => count;
// Same instance shared across all importers
// 3. Constants file:
// config.js
export const API_URL = "https://api.example.com";
export const MAX_RETRIES = 3;
export const TIMEOUT = 5000;
// 4. Type-only imports (TypeScript):
import type { User, Post } from "./types";
import { type Config, loadConfig } from "./config";Module features:
• Strict mode by default (no need for "use strict")
• Own scope (no global pollution)
• Executed once (cached on subsequent imports)
• Static structure (imports hoisted, analyzable)
• Live bindings (exports update when source changes)
FAQ
Common questions about ES modules.