Skip to main content
← ⚑ JavaScript & the browserΒ·Module C3 Β· Lesson 4
TaskInline approximation: simulate the dynamic-import pattern. On button click, log 'loading...', then resolve a Promise (use Promise.resolve({ greet: name => `hi, ${name}` })), destructure greet, log greet('Anna').

Dynamic import(): load code on demand

100 XP8 min
Theory

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.

← PreviousNext lesson β†’

Get one Python or web tip a day β€” by email

Short, hand-written, no spam. Unsubscribe in one click.