JavaScript Dynamic Modules
JavaScript Dynamic Import
Dynamic Import was introduced in ECMAScript 2020
Dynamic import is one of the most powerful features for modular and efficient code.
Dynamic Import is a way to load JavaScript modules at runtime, rather than at the start of your program.
Modern Software
Modern software splits imports into separate chunks.
Modules are downloaded only when requested - this method has many names:.
- Dynamic Import
- Code Splitting
- Lazy Loading
- Conditional Loading
Unlike Static Import (which must appear at the top of a file), Dynamic Import can be used anywhere - inside functions, conditionals, event handlers, etc.
Syntax
import("./module.js")
- The argument must be a string or expression that resolves to a path
- You must run the import inside a module script (<script type="module">)
| Type | Example | When Loaded | 
|---|---|---|
| Static | import { add } from './math.js'; | At load time | 
| Dynamic | const math = await import('./math.js'); | When needed | 
Improved Performance
Modules can improve performance by allowing tools to implement "code splitting". This means that a user's browser only needs to load the JavaScript modules required for the specific features they are using at a given moment, rather than the entire application's code at once.
While modules themselves are a language feature, when combined with bundlers like Webpack or Rollup, they can lead to performance improvements through optimizations like tree-shaking (eliminating unused code), code splitting, and minification.
How Dynamic Import Works
Dynamic Modules use modern async/await:
Example
async function run() {
  const module = await import("./math.js");
  let result = module.add(2, 3);
}
run();
math.js
// Export an "add" function
export function add(a, b) {
  return a + b;
}
Example Explained
- The script starts running
- It defines and calls run()
- Inside run(), it dynamically loads math.js
- Once loaded, it gets access to the exported function add()
- It calls add(2, 3) and gets 5
- It displays the result
| Step | Code | Explained | 
|---|---|---|
| 1 | async function run() | Define a function that can use await | 
| 2 | await import("./math.js") | Load the module file only when needed | 
| 3 | module.add(2, 3) | Use the exported function from the module | 
| 4 | run() | Start the process | 
Step 1. Define a function that can use await:
async function run() {
- This line defines an asynchronous function called run()
- The async keyword means the function can use await inside it
- The await keyword pauses the function until a Promise is resolved
- In this case, the Promise is the import of the module
Step 2. Load the module file only when needed:
const module = await import("./math.js");
- import("./math.js") defines a dynamic import
- The module math.js is loaded on demand
- math.js returns a Promise that resolves to its exported content
- The await keyword waits until the module is fully loaded
- Once loaded, the variable module contains the data exported from math.js
Step 3. Use the exported function from the module:
let result = module.add(2, 3);
- Calls the exported function add() from the imported module
- Passes in 2 and 3 as arguments
- The function adds them and returns 5
- The result is stored in result
Step 4. Start the process - Call the Function:
run();
When it runs:
- It loads the module math.js dynamically
- It waits for the module to finish loading
- It calls the add() function of the module
- It displays the result
Another Example
Example
async function run(x) {
  const module = await import("./temperatures.js");
  let celsius = module.toCelsius(x);
  document.getElementById("demo").textContent = celsius + " Celcius";
}
run(50);
temperatures.js
// Convert Fahrenheit to Celsius
export function toCelsius(farenheit) {
  return (farenheit - 32) * 5 / 9;
}
// Convert Celsius to Fahrenheit
export function toFahrenheit(celsius) {
  return (celsius * 9 / 5) + 32;
}
Dynamic Import Key Features
- Lazy Loading - Load code only when it is needed
- Performance Optimization - Reduce initial load size for faster page load
- Conditional Imports - Import different modules based on conditions.
Conditional Loading
if (user.isAdmin) {
  const adminTools = await import("./admin-tools.js");
  adminTools.init();
}
 
