As a program grows, one giant file becomes painful. You cannot find anything, names clash, and a change in one place breaks another. Modules solve this by letting you split code into separate files, and share only what you choose.
Before modules
Old pages loaded many <script> tags, and every script put its variables in one shared global space. Two files using the same name overwrote each other, and the order of the tags mattered.
With modules
Each file is its own module with its own scope. A module:
- keeps its variables private by default,
- exports the parts other files may use,
- imports what it needs from other modules.
export function add(a, b) {
return a + b;
}
export const PI = 3.14159;
import { add, PI } from "./math.js";
console.log(add(2, 3)); // 5
console.log(PI); // 3.14159
The words export and import are the ES modules syntax, part of the language standard (ECMAScript 2015 and later).
A runnable demo
Files cannot exist inside this editor, so this example loads a tiny module from a data: URL with the dynamic import() you will meet later. In a real project this would simply be import { add } from "./math.js" at the top of the file.
<script type="module">
const source = "data:text/javascript," + encodeURIComponent(`
export const add = (a, b) => a + b;
export const greet = name => "Hello, " + name;
`);
const { add, greet } = await import(source);
console.log(add(2, 3)); // → 5
console.log(greet("Maya")); // → Hello, Maya
</script>
What modules give you
| Benefit | Meaning |
|---|---|
| Organisation | one file, one job |
| No name clashes | each module has its own scope |
| Explicit dependencies | the top of each file shows what it needs |
| Reuse | import the same module in many places |
| Tooling | bundlers can remove unused code (“tree shaking”) |
Modules in browsers
Modern browsers load ES modules natively with <script type="module">, see Browser Modules. For large projects, build tools (Vite, webpack, esbuild) bundle modules for production.
Use ES modules
Use the modern import/export syntax. Older patterns, such as IIFEs, global namespaces and CommonJS (require), exist in old code, and Project Structure shows how to recognise them. They are not the preferred approach for new browser code.