0Pricing
HTML Academy · Lesson

Dynamic Import() in Modules

Load modules on demand with dynamic import().

Dynamic Import() in Modules is a free HTML Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The import() Expression

Unlike the static import declaration, import("./module.js") is an expression that returns a Promise resolving to the module's namespace. It works anywhere — inside functions, conditions, even inside non-module scripts.

Code Splitting

Dynamic import is the primary code-splitting mechanism. A route handler can defer loading the route's code until the user navigates: const mod = await import("./routes/admin.js"). The route's bytes never download until they are needed.

document.getElementById("settings-btn").addEventListener("click", async () => {
  const { renderSettings } = await import("./settings.js");
  renderSettings();
});

Returned Module Namespace

The resolved value is the module namespace — an object with the module's exports as properties. Destructure named exports inline, or access the default export as module.default.

Catching Errors

Because import() returns a promise, errors from a failed fetch or syntax error propagate to .catch(). Wrap dynamic imports in try/catch (in async functions) or .catch() to handle network failures gracefully.

try {
  const mod = await import("./optional.js");
  mod.run();
} catch (e) {
  console.warn("Optional module failed", e);
}

Conditional Loading

Load polyfills only in older browsers: if (!window.IntersectionObserver) await import("intersection-observer-polyfill"). Modern browsers skip the bytes entirely; older browsers pay the cost only when needed.

Specifier Resolution

The specifier follows the same rules as static import: relative URLs, absolute URLs, or bare names mapped via import map. Dynamic strings work too: import(`./locales/${lang}.js`), though bundlers may have trouble code-splitting this.

Caching

Each unique specifier resolves to the same module instance. The second import("./mod.js") returns the already-loaded module without a network roundtrip — making dynamic import safe to use in event handlers without worrying about repeated downloads.

Top-Level Dynamic Import

Inside a module, you can use top-level await with dynamic import to delay execution until an async-loaded helper is available. Useful for plugin systems where the plugin list is known at runtime.

// module.js
const { plugin } = await import(`./plugins/${process.env.PLUGIN}.js`);
plugin.init();

Use With React.lazy and Preact

React.lazy, Preact's `lazy` from preact/compat, and Vue's defineAsyncComponent all wrap dynamic import for component-level code splitting. The browser primitive is import(); frameworks add suspense-like loading boundaries on top.

Webpack and Vite Splitting

Bundlers see import("...") in source and emit a separate chunk for the imported module. The runtime stub fetches the chunk on first call. The author writes ES-spec import(); the bundler produces the network choreography.

Common Mistake

Calling import("X") inside a hot path (like inside a render loop) re-checks the cache on every call. While it doesn't re-download, the lookup has overhead. Store the resolved namespace in a variable after the first import.

Knowledge Check

What does import("./mod.js") return?

Summary

Dynamic import() is the on-demand cousin of the static import declaration. It returns a Promise resolving to the module namespace, enabling code splitting, conditional polyfills, and plugin systems. Modules cache after the first import, so subsequent calls are free. Bundlers emit separate chunks for each dynamic import call.

Frequently asked questions

Is the “Dynamic Import() in Modules” lesson free?

Yes — the full text of “Dynamic Import() in Modules” is free to read here on the web, and the HTML Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the HTML Academy course, upgrade to CoddyKit PRO.

What will I learn in “Dynamic Import() in Modules”?

Load modules on demand with dynamic import(). You practise HTML Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start HTML Academy?

No prior experience is required. HTML Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Dynamic Import() in Modules” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this HTML Academy lesson?

Yes. Every HTML Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. ES Module Scripts type=module
  2. Import Maps importmap
  3. Dynamic Import() in Modules
  4. Module Federation Basics
← Back to HTML Academy