| Crates.io | importmap |
| lib.rs | importmap |
| version | 0.4.0 |
| created_at | 2026-01-08 14:53:43.694372+00 |
| updated_at | 2026-01-22 23:24:34.707326+00 |
| description | Generate import maps with hashed URLs for cache busting |
| homepage | https://github.com/nym21/importmap |
| repository | https://github.com/nym21/importmap |
| max_upload_size | |
| id | 2030395 |
| size | 19,402 |
Generate import maps with content-hashed URLs. No bundler required.
ES modules load sequentially. Browser fetches main.js, parses it, discovers imports, fetches those, parses them, discovers more imports... This creates a waterfall that gets worse with deeper dependency trees.
Cache invalidation is also tricky. Change one file and users might get stale cached versions of files that import it.
This crate:
<link rel="modulepreload"> tags for all modulesThe import map lets you write clean imports (./utils.js) while the browser fetches hashed URLs (./utils.a1b2c3d4.js). Modulepreload tells the browser to fetch everything in parallel, eliminating the waterfall.
Add markers to your HTML:
<head>
<!-- IMPORTMAP -->
<!-- /IMPORTMAP -->
</head>
Run the CLI:
importmap path/to/site
Or use as a library:
use importmap::ImportMap;
let map = ImportMap::scan(dir, "")?;
let html = fs::read_to_string("index.html")?;
if let Some(updated) = map.update_html(&html) {
fs::write("index.html", updated)?;
}
The markers get replaced with:
<head>
<!-- IMPORTMAP -->
<link rel="modulepreload" href="/scripts/main.a1b2c3d4.js">
<link rel="modulepreload" href="/scripts/utils.e5f6g7h8.js">
<script type="importmap">
{
"imports": {
"/scripts/main.js": "/scripts/main.a1b2c3d4.js",
"/scripts/utils.js": "/scripts/utils.e5f6g7h8.js"
}
}
</script>
<!-- /IMPORTMAP -->
</head>
Your source files stay unchanged. The browser:
import "./utils.js" → checks import map → requests ./utils.a1b2c3d4.jsYour server must handle hashed URLs by stripping the hash and serving the original file:
Request: /scripts/main.a1b2c3d4.js
Serve: /scripts/main.js
The hash is always 8 hex characters before the extension. Set Cache-Control: immutable, max-age=31536000 for hashed URLs—the content will never change for that hash.
.js, .mjs, .css.js files (service workers), files with .development. or .dev. in the namenode_modules links)MIT