A module shares things with the export keyword, and another module takes them with import.
Exporting
Put export in front of a declaration:
export const TAX_RATE = 0.2;
export function addTax(price) {
return price * (1 + TAX_RATE);
}
export class Cart {
items = [];
}
Or list the exports at the bottom:
const TAX_RATE = 0.2;
function addTax(price) { return price * (1 + TAX_RATE); }
export { TAX_RATE, addTax };
Anything not exported stays private to the module.
Importing
import { addTax, TAX_RATE } from "./utils.js";
console.log(addTax(100)); // 120
- The names in
{ }must match what was exported. - The path starts with
./or../for your own files, and includes the.jsextension in browsers. - Imports are hoisted: they are processed before the module runs, and always at the top level of the file.
Try it
<script type="module">
// Module "utils" (normally its own file)
const utilsSource = "data:text/javascript," + encodeURIComponent(`
export const TAX_RATE = 0.2;
export function addTax(price) { return price * (1 + TAX_RATE); }
const secret = "not exported";
`);
const { addTax, TAX_RATE } = await import(utilsSource);
console.log(addTax(100)); // → 120
console.log(TAX_RATE); // → 0.2
</script>
(This demo uses dynamic import() because the module source lives in a variable. In a real project you would write import { addTax } from "./utils.js" at the top.)
Namespace import
Import everything under one name with * as:
import * as utils from "./utils.js";
utils.addTax(100);
utils.TAX_RATE;
Imports are read-only live bindings
An imported name is a view of the exporting module’s variable. You cannot assign to it from outside, but if the exporting module changes it, the importer sees the new value.
export let count = 0;
export function increment() { count++; }
import { count, increment } from "./counter.js";
console.log(count); // 0
increment();
console.log(count); // 1 (the live binding updated)
// count = 5; // TypeError: Assignment to constant variable
Side-effect imports
import "./setup.js"; // runs the module, imports nothing
A module runs once
No matter how many files import it, a module’s top-level code runs one time, and everyone shares the same instance. That makes modules a natural place for shared settings or a single store. See Module Scope.