Organizing Code with Modules
By now you have written a fair amount of JavaScript: variables, functions, objects, event listeners. But so far it has probably all lived in one file. As programs grow, one big file becomes hard to read, hard to reuse, and easy to break. Modules are JavaScript's answer: they let you split code into separate files and share pieces between them.
What a Module Is
A module is a JavaScript file that declares what it exports (the values it shares with other files) and what it imports (the values it uses from other files). Think of it like a toolbox: each module is a labeled box, and imports and exports are the handles that let boxes pass tools to each other.
Why this matters:
- Smaller files are easier to understand and fix.
- A module can be reused in many places without copying code.
- Each module keeps its variables private unless it explicitly exports them, which prevents name clashes.
Exporting Code
A module makes a value available to others with the export keyword. You can declare and export in one line:
// math.js
export function add(a, b) {
return a + b;
}
export const pi = 3.14159;You can also export one thing as the module's main output with export default:
// math.js
export default function add(a, b) {
return a + b;
}A module can have many named exports but only one default export.
Importing Code
Another file pulls those values in with the import keyword:
// app.js
import add, { pi } from './math.js';
console.log(add(2, 3)); // 5
console.log(pi); // 3.14159Here, add (without braces) refers to the default export, while { pi } is a named import. The braces must match the exported name exactly.
Using Modules in a Browser
Browsers need a hint to treat a script as a module. In your HTML, add type="module" to the script tag:
<script type="module" src="app.js"></script>With that in place, the browser runs app.js, follows its import statements, and loads math.js automatically.
Show diagram source
graph LR
A[HTML page] --> B[app.js]
B -- "import add, { pi }" --> C[math.js]
C -- "export add, pi" --> B
B --> D[Browser runs the code]Common Beginner Mistakes
- Forgetting
type="module"— the browser then ignores yourimportstatements and throws a syntax error. - Mismatched names —
import { Add }fails when the export isadd. Names are case-sensitive. - Missing file path prefix — in browsers, imports need a path like
./math.js, not justmath.js. - Wrong paths — the path is relative to the importing file, so check which folder each file is in.
callout note A module's variables are private by default. If another file can't see a value, ask yourself: "Did I export it, and did I import it with the exact same name?"
Why It's Worth the Effort
Every future step in your learning—frameworks, build tools, shared libraries—assumes you understand modules. Learning the pattern now, with two small files, makes all of it easier later.
exercise Q: You have utils.js with export function greet(name) { return Hi, ${name}; }. Write the import statement for greet in main.js. A: import { greet } from './utils.js';
exercise Q: What changes when greet is exported with export default instead? A: The import drops the braces and you can name it anything: import greet from './utils.js';
estimate minutes: 30
Spotted a mistake, or code that does not work?