Member-only story
Dynamic Import, Code Splitting, Lazy Loading, and Error Boundaries
A detailed guide

This article is a detailed guide on how to use dynamic import, which enables code splitting and lazy loading. It also describes how to use error boundaries to catch errors.
Is import()
a Function?
Yes, but no.
import()
is currently in stage 4 of the TC39 process. It is a function-like module loading syntactic form in JavaScript.
It acts in many ways like a function:
- It is invoked by the
()
operator. - It returns a promise for the module namespace object of the requested module, which is created after fetching, instantiating, and evaluating all of the module’s dependencies, as well as the module itself.
But it is not a function:
- It is a syntactic form that just happens to use parentheses, similar to
super()
. - It does not inherit from
Function.prototype
. Therefore, it cannot be invoked withapply
orcall
. - It does not inherit from
Object.prototype
. Therefore, it cannot be used as a variable.const a = import
is illegal.
Another interesting point:import.meta
, a stage 4 TC39 proposal, exposes context-specific metadata to a JavaScript module. It contains information about the module, such as the module’s URL. import.meta
is an object with a null
prototype. However, it is extensible, and its properties are writable, configurable, and enumerable.
Dynamic import, code splitting, lazy loading, and error boundaries are interesting technologies. Do you want to know more?
What Is Dynamic Import?
In contrast to importing modules statically, dynamic import is a design pattern to defer an object’s initialization until the point at which it is needed. Dynamic import enables code splitting and lazy loading. This can dramatically improve the application’s performance.
It is done by import()
:
import("/path/to/import-module.js") // .js can be skipped
.then((module) => {
// do something with the module
});