Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

Dynamic import is a function-like expression in JavaScript that asynchronously loads an ECMAScript module at runtime. Unlike static import declarations—which are statically analyzed, resolved, and linked into a dependency graph prior to execution—dynamic imports return a Promise and can be executed conditionally or on-demand within any lexical scope. While the actual evaluation of the module code happens at runtime for both, static imports are evaluated strictly before the importing module executes, whereas dynamic imports are evaluated exactly when the import() expression is invoked.

Syntax

import(moduleSpecifier)
import(moduleSpecifier, options)
  • moduleSpecifier: A string, or an expression that evaluates to a string, representing the path to the module.
  • options (Optional): An object containing import options. This is standardly used for Import Attributes to specify the module format or type.

Technical Mechanics

When the JavaScript engine encounters an import() expression, it initiates the fetch, instantiation, and evaluation of the target module asynchronously. 1. The Module Namespace Object and Live Bindings The Promise returned by import() resolves to a module namespace object. Crucially, this object does not act as a static snapshot; it provides live bindings to the exports of the requested module. If an exported variable is updated from within the loaded module, the new value is immediately reflected on the module namespace object returned by the dynamic import.
// Using async/await
async function loadMath() {
  try {
    const mathModule = await import('./math.js');
    
    // Accessing a named export
    const sum = mathModule.add(5, 10);
    
    // Accessing the default export
    const defaultVal = mathModule.default();
  } catch (error) {
    console.error("Failed to load module:", error);
  }
}
Because default is a reserved keyword in JavaScript, you must alias it when destructuring the module namespace object:
const { default: DefaultClass, namedFunction } = await import('./module.js');
2. Import Attributes The optional second argument allows the passing of attributes to the module loader, dictating how the module should be parsed and instantiated.
// Importing a JSON module using the options argument
const config = await import('./config.json', { with: { type: 'json' } });
console.log(config.default.version);
3. Runtime Specifier Evaluation Because dynamic imports are resolved at runtime, the moduleSpecifier does not need to be a static string literal. It can be a dynamically computed value, such as a variable or a template literal.
const version = 'v2';
const moduleName = 'parser';

// The specifier is computed at runtime
import(`./libs/${version}/${moduleName}.js`)
  .then((module) => module.init())
  .catch((err) => console.error(err));
4. Lexical Placement Static import statements are strictly constrained to the top level of a module to allow the JavaScript engine to statically analyze the dependency graph and create Module Records before execution. Dynamic import() bypasses this constraint and can be placed inside functions, if statements, try/catch blocks, or loops.
if (condition) {
  // Valid: Nested inside a block
  import('./feature.js').then(m => m.run());
}

Static vs. Dynamic Import Comparison

CharacteristicStatic importDynamic import()
Resolution & LinkingPre-execution (Parse/Link phase)Runtime
Evaluation PhaseRuntime (Strictly ordered before importing module)Runtime (Upon expression execution)
Return ValueNone (Declarative syntax)Promise<ModuleNamespaceObject>
Binding MechanismLive bindingsLive bindings (via the resolved namespace object)
SpecifierStrict string literalAny expression evaluating to a string
PlacementTop-level onlyAnywhere (functions, blocks, etc.)
EnvironmentModules only (type="module")Modules and standard Scripts

Caching Behavior

The JavaScript engine maintains a module map. If import() is called multiple times with the same resolved moduleSpecifier, the engine fetches, instantiates, and evaluates the module only once. Subsequent calls return a Promise that resolves immediately with the already-cached module namespace object.
Master JavaScript with Deep Grasping Methodology!Learn More