Import Maps 101


As web developers, the use of external libraries has saved us a lot of time and effort, allowing us to build apps faster and more efficiently. In this article, I will be introducing you to a spec called import maps to control the behaviour of importing these libraries.
Introduction
Typically, using external libraries in browsers requires bundlers/build tools such as webpack or browserify in order to parse the code and allow the use of import statements. These are known as bare modules. Modules which are imported without an absolute or relative URL cannot be imported in the browser without bundle tools.
For example, importing the lodash
package would be written as:
import _ from "lodash";
This bare import specifier makes it easier to write and manage code, without having to write absolute/relative URLs of the library.
What exactly does Import Maps solve?
With bundlers and build tools solving the issue with bare imports, you may now wonder what problem import maps actually solves.
The short answer is: import maps can be used to load bare modules without the need for bundlers.
The longer explanation is that normally, code gets bundles altogether into a large file import maps can be used to control the behaviour of importing libraries, such as when it is needed at runtime, remapping of URL-like specifiers, scoping, dynamic imports, etc. This allows better caching for module script graphs and better developing performance.
Example Usage
Let's take a look at an example implementation of import maps. In this tutorial, we will learn how to import a bare module like dayjs without the use of a bundler.
Step 1: Create index.html and index.js
First, let's create a new HTML page index.html
and script called index.js
.
In our index.html
, let's import index.js
as a module like so:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Import Maps Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./index.js"></script>
</head>
<body>
</body>
</html>
Step 2: Write a simple script in index.js
Now let's write something simple that uses dayjs. For this example, I am writing a script that prints out the current datetime every second.
import dayjs from "dayjs";
const el = document.createElement("h1");
document.body.appendChild(el);
setInterval(() => {
el.innerHTML = dayjs(Date.now()).format("YYYY-MM-DD HH:mm:ss");
}, 1000);
Step 3: Add import maps to import the library
If you try running the page now, it obviously would not work because the dayjs we imported in index.js
is a bare module. You will see the following error:
So let's use import maps to resolve this error. Back in index.html
add the following:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Import Maps Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Add this importmap before index.js -->
<script type="importmap">
{
"imports": {
"dayjs": "https://cdn.skypack.dev/dayjs@1.11.5"
}
}
</script>
<script type="module" src="./index.js"></script>
</head>
<body>
</body>
</html>
Note: When implementing import maps, ensure that it is added before the first module load is started, in this example,
index.js
.
Now let's run the page and our script should be running with no issues.
Scopes
Another important aspect to know about import maps is scoping, which allows the use of multiple versions of the same package in a specified scope.
For example, the code below specifies that any module in /src
path will use the https://cdn.skypack.dev/dayjs@1.10.7
package, while anything outside that path will use https://cdn.skypack.dev/dayjs@1.11.5
.
<script type="importmap">
{
"imports": {
"dayjs": "https://cdn.skypack.dev/dayjs@1.11.5"
},
"scopes": {
"/src": {
"dayjs": "https://cdn.skypack.dev/dayjs@1.10.7"
}
}
}
</script>
This is useful in the case where you need to work with multiple versions of the same package simultaneously for various reasons such as compatibility with other libraries, ensuring legacy systems can still run and so on.
VS Code Extension
Alternatively, instead of writing our import maps script, there is a VS Code extension which can automatically generates and injects import maps for modules and HTML pages.
You can learn more about this extension here.
Other Usages
There are also many other uses of import maps besides allowing bare module imports such as:
Importing modules within modules
Allow extension-less imports
Remapping imports (mapping away hashes)
You may learn more about these useful features in the official documentation.
Browser Support
In terms of browser support, at the time of this article (Aug 2022), it is supported in Chromium-based browsers only (i.e. Chrome, Edge).
More of this information can be found in the image below:
Polyfills
If you want import maps to be supported in any browser, there is an ES Module Shims polyfill which is compatible with any browser that has baseline ES Module Support (i.e. Edge 17+, Firefox 60+, Safari 10.1+, and Chrome 61+).
To use it, simply add the polyfill script with an async
attribute and add an import map or module script below:
<!-- import polyfill here -->
<script async src="https://ga.jspm.io/npm:es-module-shims@1.5.16/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"react": "https://ga.jspm.io/npm:react@18.0.0-rc.0/index.js"
},
"scopes": {
"https://ga.jspm.io/npm:react@18.0.0-rc.0/": {
"object-assign": "https://ga.jspm.io/npm:object-assign@4.1.1/index.js"
}
}
}
</script>
<script type="module">
import react from 'react';
console.log(react);
</script>
Example code taken from here
Conclusion
In this article, we learned about import maps, what problems it can solve and how to implement it. Thanks for reading, I hope it has been a helpful article in getting you started with import maps.
Please read more about it in the References section below. Leave a like and share this article if it is insightful! Cheers!
References
https://github.com/WICG/import-maps
https://wicg.github.io/import-maps/
https://github.com/guybedford/es-module-shims
https://caniuse.com/import-maps
https://marketplace.visualstudio.com/items?itemName=JSPM.jspm-vscode
Subscribe to my newsletter
Read articles from Victoria Lo directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Victoria Lo
Victoria Lo
I'm a solutions engineer, GitHub Star, WomenDevsSG Director and podcaster who loves to build projects and share valuable tips for new programmers on this blog at lo-victoria.com. Fun fact: speak 5 languages (English, Mandarin, Bahasa Indonesia, Japanese, Korean). Feel free to reach out to me in any of these languages :)