import()
Runtime function-like syntax that loads a module.
Dynamic import loads a module on demand and returns a promise.
button.addEventListener("click", async () => {
const module = await import("./chart.js");
module.renderChart();
});
Modules & Code Organization
Static imports are loaded as part of the module graph. Dynamic import runs at runtime and returns a promise for the module namespace.
This is useful for optional features, heavy UI panels, admin tools or routes that users may never open.
Because dynamic import is async, it needs loading and failure states like any other async operation.
Runtime function-like syntax that loads a module.
Resolves to the module namespace object.
Bundlers can create separate chunks.
Load only when needed.
Examples
status.textContent = "Loading feature...";
try {
const feature = await import("./feature.js");
feature.start();
} catch {
status.textContent = "Feature could not be loaded.";
}
const feature = await import("./feature.js");
feature.start();
Code patterns
These examples focus on imports, exports, module boundaries, on-demand loading and file structure you can use in real projects.
Load feature code only when requested.
button.addEventListener("click", async () => {
const feature = await import("./feature.js");
feature.start();
});
Pull named exports from the loaded module.
const { renderChart } = await import("./chart.js");
renderChart();
Dynamic import can reject.
try {
const module = await import("./panel.js");
} catch (error) {
showError("Could not load panel.");
}
Avoid loading the same optional module repeatedly.
let panelPromise;
function loadPanel() {
panelPromise ??= import("./panel.js");
return panelPromise;
}
Rules that matter
A module system only helps when files have clear jobs, small public APIs and predictable import paths.
They are simpler and easier to analyze.
Load heavy features only when needed.
Users should know the click did something.
Missing chunks or network failures can happen.
Avoid repeated work in your own logic.
Highly dynamic paths can confuse bundlers and maintainers.
Production thinking
Dynamic import is how larger apps stay fast without loading every feature up front.
Optional panels loaded dynamically should announce loading and errors clearly.
Production bundlers can split dynamic imports into separate chunks, but those chunks need error handling.
Critical content should not hide behind optional dynamic imports unless rendering is guaranteed.
Live code lab
The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.
Mini assignment
Practice assignment
Try it yourself
Self-check
If you can explain what a file exports, what it imports and why it exists, the module structure is doing its job.
Senior audit upgrade
Use these references when browser support, syntax details or proposal status matters.