What is dynamic import()?
Dynamic import() loads a module on demand at runtime, returning a Promise, instead of importing it statically at the top of a file.
On demand — load code only when it's actually needed.
Returns a Promise — await it or use .then to get the module.
Powers code splitting and lazy loading — ship less JavaScript upfront and load features when used.
// Dynamic import — loads on demand
async function loadEditor() {
const { Editor } = await import('./heavy-editor.js');
return new Editor();
}
// Conditional loading
if (needsPolyfill) {
await import('./polyfill.js');
}
// Route-based code splitting
const routes = {
'/home': () => import('./pages/home.js'),
'/about': () => import('./pages/about.js'),
'/settings': () => import('./pages/settings.js')
};
async function navigate(path) {
const module = await routes[path]();
module.default.render();
}
// Computed path
const lang = 'en';
const translations = await import(`./i18n/${lang}.js`);
// Fallback pattern
let parser;
try {
parser = await import('fast-parser');
} catch {
parser = await import('fallback-parser');
}import() returns a Promise that resolves to the module's exports. loadEditor loads a heavy dependency only when called (not on page load). The route object maps paths to lazy-loading functions.
Computed paths enable dynamic file selection. The fallback pattern tries a preferred module and falls back to an alternative.
Dynamic import() enables code splitting without a bundler plugin. Show the route-based splitting pattern (load page components on navigation).
Know that it returns a Promise (must await or .then). Computed paths and conditional loading are the key advantages over static import.