Modern JavaScript uses ES Modules (ESM) to organize code into multiple files. Instead of writing everything in a single file, you can split your code into reusable modules and connect them using export and import.
π What is a Module?
A module is simply a JavaScript file. Every module has its own scope, meaning variables and functions inside one file are not automatically available in another file.
Example:
Project Structure
project/
βββ math.js
βββ app.js
βββ user.js
βββ index.htmlπ― Why Use Modules?
- β Better code organization
- β Reusable functions
- β Easy maintenance
- β Avoid global variables
- β Faster development
- β Cleaner architecture
π¦ Export in JavaScript
export makes variables, functions, classes, or objects available for use in other modules.
1οΈβ£ Named Export
Named exports allow exporting multiple values from the same file.
math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}Import them like this:
app.js
import { PI, add, subtract } from "./math.js";
console.log(PI);
console.log(add(5, 2));
console.log(subtract(10, 3));Note
2οΈβ£ Exporting Later
math.js
const PI = 3.14;
function add(a, b) {
return a + b;
}
export { PI, add };3οΈβ£ Renaming Exports
math.js
const PI = 3.14;
export { PI as CirclePI };app.js
import { CirclePI } from "./math.js";
console.log(CirclePI);π Default Export
A module can have only one default export.
user.js
export default function greet() {
console.log("Hello World");
}Import it without curly braces.
app.js
import greet from "./user.js";
greet();Note
Example
import sayHello from "./user.js";
sayHello();π― Default Export of Variables
config.js
const API_URL = "https://example.com";
export default API_URL;app.js
import url from "./config.js";
console.log(url);π· Default Export of Classes
Person.js
export default class Person {
constructor(name){
this.name = name;
}
greet(){
console.log("Hello " + this.name);
}
}app.js
import Person from "./Person.js";
const p = new Person("John");
p.greet();π Multiple Named Exports
math.js
export const PI = 3.14;
export function square(n){
return n*n;
}
export function cube(n){
return n*n*n;
}app.js
import { PI, square, cube } from "./math.js";
console.log(square(5));
console.log(cube(3));π¨ Import Everything
Use * as to import all named exports into a single object.
app.js
import * as MathUtils from "./math.js";
console.log(MathUtils.PI);
console.log(MathUtils.square(5));
console.log(MathUtils.cube(4));π― Rename During Import
app.js
import { add as sum } from "./math.js";
console.log(sum(5,5));π¦ Mixing Default and Named Export
math.js
export const PI = 3.14;
export function add(a,b){
return a+b;
}
export default function greet(){
console.log("Hello");
}app.js
import greet, { PI, add } from "./math.js";
greet();
console.log(PI);
console.log(add(4,5));π Re-export
math.js
export function add(a,b){
return a+b;
}index.js
export { add } from "./math.js";app.js
import { add } from "./index.js";
console.log(add(2,3));π₯ Dynamic Import
Dynamic imports load modules only when needed, which can improve application performance.
app.js
async function loadMath(){
const math = await import("./math.js");
console.log(math.add(5,5));
}
loadMath();Note
π Using Modules in HTML
index.html
<!DOCTYPE html>
<html>
<head>
<title>Modules</title>
</head>
<body>
<script type="module" src="app.js"></script>
</body>
</html>Note
π Example Project
Folder Structure
project/
β
βββ index.html
βββ app.js
βββ math.js
βββ user.jsmath.js
math.js
export function add(a,b){
return a+b;
}
export function multiply(a,b){
return a*b;
}user.js
user.js
export default function welcome(){
console.log("Welcome");
}app.js
app.js
import welcome from "./user.js";
import { add, multiply } from "./math.js";
welcome();
console.log(add(5,3));
console.log(multiply(5,3));β οΈ Common Errors
| Error | Reason | Solution |
|---|---|---|
| Cannot use import statement | Module not enabled | Use type="module" |
| Module not found | Wrong file path | Check relative path and extension |
| Named export not found | Incorrect export name | Match the exact exported identifier |
| Unexpected token 'export' | Environment doesn't support ES Modules | Enable ESM or use a bundler/runtime configuration |
π‘ Best Practices
- Use named exports for utility functions.
- Use default exports when a file exposes one primary value.
- Keep modules small and focused on a single responsibility.
- Use meaningful file and export names.
- Avoid circular dependencies between modules.
- Always include the correct relative path (for example, ./math.js) when importing in browsers.
π§ Quick Comparison
| Feature | Named Export | Default Export |
|---|---|---|
| Number per file | Unlimited | One |
| Uses curly braces when importing | Yes | No |
| Name must match export | Yes (unless aliased) | No |
| Best use case | Multiple utilities | Main function, class, or object of a module |
π Summary
You learned how to:
- Create JavaScript modules.
- Export variables, functions, classes, and objects.
- Use named exports and default exports.
- Import modules in different ways, including aliasing and namespace imports.
- Re-export modules through a central file.
- Use dynamic imports for lazy loading.
- Load ES modules correctly in the browser with type="module".
- Follow best practices and troubleshoot common module errors.