Glossary / Dynamic imports

Dynamic imports

Dynamic import() asynchronously loads a module and fulfills with a module namespace object. Unlike static imports, it can appear in expressions and conditional control flow, supporting lazy loading, feature-gated code, and many bundler-driven code-splitting patterns.

Behavior and usage

async function openEditor() {
  const { createEditor } = await import('./editor.js');
  return createEditor();
}

import(specifier) returns a promise. Resolution, fetching/loading, linking, or evaluation failures reject it. The result has the module's exports, including default when present. Repeated imports of the same resolved module generally reuse the loader's module instance/cache, though cache identity and invalidation are host-specific.

Dynamic import does not mean “load only on click” by itself: code must call it at the desired point, and bundler configuration determines chunk boundaries and prefetch behavior. Computed specifiers can make bundlers emit a context of possible modules or fail static analysis. Browser specifiers follow URL resolution; Node follows its resolver and package conditions.

Performance and security

Lazy loading reduces initial transfer and evaluation work only when it moves code out of startup and deployment serves the resulting chunks correctly. It adds network latency, failure paths, and chunk caching/versioning concerns. Do not interpolate untrusted strings into module specifiers; overly broad dynamic loading can expose unintended code and defeat optimization.

Engineering guidance

Use dynamic imports at genuine demand boundaries, show loading and failure states, and handle rejection. Measure initial and interaction latency. Ensure cached entry points cannot request deleted chunks during deploy transitions; use atomic asset deployment or compatible content-hashed chunks.

Interview questions

  1. What does import() return? A promise fulfilled with the module namespace object.
  2. Can it be called conditionally? Yes, unlike static import declarations.
  3. Does it always create a separate file? No; bundler output depends on configuration.
  4. What failures must callers handle? Resolution, network/loading, linking, and evaluation errors.
  5. How does it affect performance? It can defer startup cost but adds latency and failure risk at the later use point.

References