Suggest an editImprove this articleRefine the answer for “Dynamic import()”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`import()` is a function that loads a module at runtime rather than at page load time, and returns a Promise resolving to the module's exports object.** A regular static `import` runs the moment the application starts, even if the module is never needed, while a dynamic one loads the code only when it is actually required. That shrinks the main bundle, speeds up the first page load, and makes it possible to pull code in on demand. Bundlers (Webpack, Vite, Rollup) see `import()` and automatically split that module into a separate chunk, which is exactly the code splitting mechanism. You can call `import()` anywhere: inside a function, an event handler or a condition. ```javascript button.addEventListener('click', async () => { const { showModal } = await import('./modal.js'); showModal(); }); ``` **Key point:** `import()` is an asynchronous, on-demand module load that returns a Promise and gives you code splitting and lazy loading.Shown above the full answer for quick recall.Answer (EN)Image**`import()` is a function that lets you import a module dynamically at runtime, rather than at page load time the way a regular `import` does.** It returns a Promise that resolves to an object holding the module's exports. ## Theory ### TL;DR - `import()` loads a module at the moment it is called, not when the application starts. - It returns a Promise resolving to `{ default, ...namedExports }`. - It shrinks the main bundle and speeds up the first load. - Bundlers move every dynamic import into its own chunk, which is code splitting. - It can be called anywhere: in a function, in a condition, in an event handler. - It is supported in every modern browser and in Node.js from version 14. ### Quick example ```javascript // Static import, runs while the module is being loaded import { add } from './math.js'; // Dynamic import, runs when we call it const math = await import('./math.js'); console.log(math.add(2, 3)); ``` A regular `import` is static: it loads immediately when the application starts, even if the module is never needed. `import()` is asynchronous: it loads the module only when that is genuinely required. As a result the main bundle gets smaller (together with code splitting), the initial page load gets faster, and code can be pulled in on demand. ### Syntax, and what import() returns ```javascript import(modulePath) .then((module) => { // module is an object holding the exports module.default(); // if the export was default module.someFunction(); // if it was a named export }) .catch(console.error); ``` or with `async/await`: ```javascript async function loadMath() { const math = await import('./math.js'); console.log(math.add(2, 3)); } ``` `import()` returns a Promise that either: - resolves successfully and gives the module object `{ default, ...namedExports }`; - or rejects and lands in `catch()`, if the file was not found or the download failed. ### Lazy loading and conditional imports ```javascript button.addEventListener('click', async () => { const { showModal } = await import('./modal.js'); showModal(); }); ``` Here the `modal.js` module is loaded only on the click, not during the initial page load. A conditional import works the same way: ```javascript if (user.isAdmin) { const admin = await import('./admin-panel.js'); admin.init(); } ``` The module loads only if it is needed, that is for administrators. Ordinary users never download the extra code. The path can be built from a template string: ```javascript const moduleName = 'chart'; const module = await import(`./plugins/${moduleName}.js`); ``` But there is a catch: the path has to be known to the bundler in advance, otherwise it may leave the file out of the build. In practice the bundler takes the static part of the path (`./plugins/`) and adds every file in that folder to the bundle. ### How it works in bundlers In bundlers such as Webpack, Vite or Rollup, a call to `import()` automatically creates a separate chunk, that is a separate file. For example: ```javascript import('./analytics.js'); ``` creates a separate file `analytics-XYZ.chunk.js`, which is downloaded only when `import()` is called. That is exactly the code splitting mechanism: loading code dynamically. ### Differences from a regular import | Property | `import` (static) | `import()` (dynamic) | | --- | --- | --- | | Syntax | `import { x } from 'y'` | `await import('y')` | | When it runs | While the module is loaded | At runtime, when called | | Asynchrony | Synchronous at build level | Asynchronous, a Promise | | Where it is written | At the top of the file | Anywhere: in a function, in a condition | | Used for | The main application code | Lazy modules, code splitting | ### An example in React ```jsx import React, { lazy, Suspense } from 'react'; const Settings = lazy(() => import('./Settings')); export default function App() { return ( <Suspense fallback={<p>Loading...</p>}> <Settings /> </Suspense> ); } ``` Here React uses `import()` under the hood. The `Settings` component is loaded only when it is actually rendered. Summary: | Key idea | Meaning | | --- | --- | | What it does | Loads a module asynchronously at runtime | | What it returns | A Promise resolving to the exports object | | What it is for | Lazy loading, code splitting, conditional imports | | Benefits | Faster loading, a smaller bundle | | Compatibility | Every modern browser and Node.js 14+ | ### Common mistakes - **Forgetting that it is a Promise.** `const m = import('./a.js'); m.add(1, 2)` does not work, because `m` is a Promise; you need `await` or `.then()`. - **Treating a default export as a named one.** The module object keeps `default` as its own field, so a default export needs `(await import('./a.js')).default`. - **Building the path entirely dynamically.** The bundler cannot analyse `await import(userInput)`; it needs at least a static base for the path. - **Not handling a failed load.** The network can drop, and without a `catch()` the user gets a blank screen instead of a message or a retry. - **Splitting the code too finely.** Dozens of micro-chunks mean dozens of requests, and the overhead eats the benefit of code splitting. - **Lazy loading something needed immediately.** If a module is required by the first screen, a dynamic import only adds latency instead of removing it.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.