← All material

Core JavaScript · 7 of 9

Dynamic import()

Some code is only needed sometimes — a chart library behind a button nobody may click, an admin panel most users never open. Loading it up front costs everyone, even the people who never trigger it.

button.addEventListener("click", async () => {
  const { renderChart } = await import("./chart.js");
  renderChart(data);
});

import() is a function, not a static declaration — unlike a top-level import, you can call it anywhere, including conditionally, inside an event handler, after a check. It returns a promise for the module's exports, so it slots straight into await.

A bundler treats each import() call as a split point: the code in chart.js is built into its own file and only downloaded the first time this line actually runs. Click the button once and it fetches; never click it and it never loads at all. This is the mechanism route-based and feature-based code-splitting are built on.