Dynamic import(): load code on demand
import() as a function
Static imports run at module-load time. import() as a function call returns a Promise that resolves to the module:
const { format } = await import("./big-formatter.js");
console.log(format(today));The file isn't fetched until import() runs. That means you can lazy-load chunks of your app β admin pages, optional features, polyfills you only need on old browsers.
The classic example
button.addEventListener("click", async () => {
const { default: heavyEditor } = await import("./editor.js");
heavyEditor.mount("#workspace");
});The editor module is fetched the first time the user clicks the button. Until then, none of its bytes are downloaded.
Why bundlers care
import() is a hint to bundlers ("create a separate chunk"). Webpack, Vite, esbuild all turn each dynamic import into its own .js chunk, lazy-loaded over fetch. That's how you ship a 50KB initial bundle that grows to 500KB only when users explore deeper.
Catch errors
try {
const mod = await import("./optional.js");
} catch (e) {
// module failed to load β fall back gracefully
}Static imports throw at module-load (whole page breaks). Dynamic imports can fail at runtime β wrap them in try/catch if the module is genuinely optional.
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial β card required, cancel anytime.
Sign up β free trial βFirst 10 lessons in each track are free. No card needed for those.