FSM Full Stack Masterclass
Platform under construction
JavaScript course badge

Modules & Code Organization

Advanced

Dynamic Import

Dynamic import loads a module on demand and returns a promise.

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

Modules & Code Organization

Use dynamic import when code is only needed later.

Static imports are loaded as part of the module graph. Dynamic import runs at runtime and returns a promise for the module namespace.

This is useful for optional features, heavy UI panels, admin tools or routes that users may never open.

Because dynamic import is async, it needs loading and failure states like any other async operation.

import()

Runtime function-like syntax that loads a module.

Promise result

Resolves to the module namespace object.

Code splitting

Bundlers can create separate chunks.

Optional feature

Load only when needed.

Examples

Good module code makes dependencies visible instead of magical.

Show loading and handle failure

status.textContent = "Loading feature...";

try {
  const feature = await import("./feature.js");
  feature.start();
} catch {
  status.textContent = "Feature could not be loaded.";
}

Loading optional code with no state

const feature = await import("./feature.js");
feature.start();

Code patterns

Reusable examples for quick reference.

These examples focus on imports, exports, module boundaries, on-demand loading and file structure you can use in real projects.

Load on click

Load feature code only when requested.

button.addEventListener("click", async () => {
  const feature = await import("./feature.js");
  feature.start();
});

Destructure export

Pull named exports from the loaded module.

const { renderChart } = await import("./chart.js");
renderChart();

Handle failure

Dynamic import can reject.

try {
  const module = await import("./panel.js");
} catch (error) {
  showError("Could not load panel.");
}

Cache promise

Avoid loading the same optional module repeatedly.

let panelPromise;
function loadPanel() {
  panelPromise ??= import("./panel.js");
  return panelPromise;
}

Rules that matter

Organize by responsibility.

A module system only helps when files have clear jobs, small public APIs and predictable import paths.

Use static imports by default

They are simpler and easier to analyze.

Use dynamic imports for optional code

Load heavy features only when needed.

Handle loading state

Users should know the click did something.

Handle rejection

Missing chunks or network failures can happen.

Cache repeated imports when useful

Avoid repeated work in your own logic.

Keep paths predictable

Highly dynamic paths can confuse bundlers and maintainers.

Production thinking

A project that is easy to navigate is easier to debug, test and grow.

Why does this matter?

Dynamic import is how larger apps stay fast without loading every feature up front.

Accessibility

Optional panels loaded dynamically should announce loading and errors clearly.

Production note

Production bundlers can split dynamic imports into separate chunks, but those chunks need error handling.

SEO note

Critical content should not hide behind optional dynamic imports unless rendering is guaranteed.

Live code lab

Change the HTML, CSS or JavaScript and run the result.

The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.

Mini assignment

Try this now.

  • Add a fake failure path.
  • Disable the button while loading.
  • Write the real import() statement as a comment.

Practice assignment

Do this before moving to the next topic.

  1. Identify one optional feature.
  2. Write a dynamic import.
  3. Add loading and failure UI.

Try it yourself

Simulate dynamic import flow

Live preview

Self-check

Before you continue, prove that you understand Dynamic Import.

Advanced

If you can explain what a file exports, what it imports and why it exists, the module structure is doing its job.

  1. Can you explain import()?
  2. Can you explain why it returns a promise?
  3. Can you explain code splitting?
  4. Can you explain when static imports are better?
  5. Can you explain why loading state matters?

Senior audit upgrade

Extra production context for Dynamic Import.