JavaScript Dynamic Imports

Load Code Only When You Need It

JavaScript Dynamic Imports

`await import("./mod.js")` loads a module on demand, at runtime. Great for code-splitting and conditional loading.

3 min read Level 3/5 #modules#dynamic-import#code-splitting
What you'll learn
  • Use `await import(...)` to load modules at runtime
  • Recognize when dynamic imports are the right tool

import declarations run statically — they load when the file loads. Dynamic imports load a module on demand at runtime, with the import() function. It returns a Promise that resolves to the module.

app.js
async function showChart() {
  // load the chart module only when needed
  const chart = await import("./chart.js");
  chart.render();
}

Why Bother?

Code splitting

For large apps, loading every module up front makes the first page slow. Dynamic imports let your bundler split code into chunks that load on demand.

Conditional loading

Some features only run in certain environments or for certain users. Load the code only if you’re going to use it.

if (user.isAdmin) {
  const admin = await import("./admin-tools.js");
  admin.init();
}

Lazy interactivity

Don’t load the comments-section code until the user scrolls to it. Don’t load the date-picker until the input is focused.

Default vs Named

Dynamic imports return the whole module namespace — same as import * as. Pull out what you want:

const mod = await import("./math.js");
console.log(mod.PI);           // named export
console.log(mod.default);      // default export, if any

// Or destructure:
const { area, default: User } = await import("./mod.js");

In Non-Module Contexts

Dynamic imports work even in plain (non-module) scripts — useful for legacy codebases that want to gradually adopt modules.

<script>
  import("./modern.js").then(({ greet }) => greet("Ada"));
</script>

A Real Example

A button that loads a heavy feature only when clicked:

document.querySelector("#analyze")?.addEventListener("click", async () => {
  const { runAnalysis } = await import("./analytics.js");
  await runAnalysis();
});

The user pays the download cost only when they actually click the button. Your initial page weight stays low.

When NOT To Dynamic-Import

  • For modules you’ll always need on page load — static import is faster and clearer.
  • For tiny modules — the overhead of an extra network round trip isn’t worth it.

Up Next

Before Promises (and async/await), JavaScript handled async work with callbacks. Worth understanding — they’re still everywhere.

JavaScript Callbacks →