ReviseAlgo Logo

Modules & Bundling

Dynamic Imports — import()

Master dynamic module imports in JavaScript. Learn how dynamic import() loads modules asynchronously on demand, improving startup performance.

Last Updated: July 15, 2026 10 min read

1. Introduction

Standard import statements are static: they must be declared at the top level of files and load modules immediately during compilation. Dynamic Imports use the functional import(modulePath) syntax to load modules asynchronously at runtime, enabling code splitting and on-demand loading.

2. Why It Matters

Loading all scripts at once increases initial page load times. Dynamic imports allow you to load modules on demand (for example, loading an analytics script only after the user logs in, or loading a heavy chart library only when the user clicks a tab), reducing initial bundle sizes.

3. Real-World Analogy

Think of a Restaurant Menu Ordering System:

  • Static Imports (Pre-cooking all items): A kitchen that prepares every single dish on the menu before the restaurant opens (highest memory usage and preparation time). If a customer only orders salad, the prepared steaks are wasted.
  • Dynamic Imports (Cook to Order): The kitchen sits ready. When a customer orders a steak (clicks a button), the chef prepares and serves the steak asynchronously (on-demand loading), saving resources.

4. The import() Function

The import() syntax behaves like a function call that returns a Promise resolving to the module's namespace object:

5. Dynamic Imports with Async/Await

You can combine dynamic imports with async/await syntax to write clean asynchronous code:

6. Practical Example

This script demonstrates loading a translation module dynamically based on the user's browser language setting:

7. Common Mistakes

  • Trying to use static syntax inside execution blocks: Standard import declarations are parsed statically and must be placed at the top level of files. Declaring them inside functions or loops throws a SyntaxError. Use the functional import() syntax instead for dynamic loading.

8. Quick Quiz

Q1: What does the functional import() syntax return?

A) The exported default class directly

B) A Promise that resolves to the module's namespace object

Answer: B — The functional import() call returns a Promise resolving to the module's namespace object, which contains all exports.

9. Scenario-Based Challenge

The Conditional Analytics Tracker:

An application tracks user interactions. To respect privacy options, load the analytics library: ./analytics.js only if the user has consented to tracking (window.localStorage.getItem("consent") === "granted"). Write this conditional loader using dynamic imports.

10. Debugging Exercise

Explain why this dynamic import handler fails to access the default export class:

// button.js
export default class Button {
  render() { return 'rendered'; }
}
// app.js
async function renderWidget() {
  const widget = await import('./button.js');
  // Bug: trying to instantiate the module namespace object directly!
  const btn = new widget(); // throws TypeError: widget is not a constructor! Why?
}
View Solution

Diagnosis: The import() Promise resolves to a module namespace object, not the default export itself. The default export is accessible via the default property on the resolved object.

Fix: Access the default export using the default property, or destructure the property during import:

async function renderWidget() {
  const { default: Button } = await import('./button.js'); // Destructure default
  const btn = new Button(); // Works!
}

11. Interview Questions

🟢 Q1: Compare static imports and dynamic imports and explain their differences in loading behavior.

Answer:
Static Imports: Declared at the top level of files using the import keyword. They are parsed and loaded statically before the script runs, which blocks execution until all modules are loaded.
Dynamic Imports: Called dynamically using the import() function syntax. They load modules asynchronously at runtime, returning a Promise. This design allows you to load modules on demand, improving startup performance.

12. Production Considerations

  • Code Splitting: Most modern bundlers (like Webpack or Rollup) automatically create separate chunk files (code splitting) for any dynamic imports they encounter, saving bandwidth during initial page loads.