importmap
Generate import maps with content-hashed URLs. No bundler required.
Problem
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.
Solution
This crate:
- Scans your JS/MJS/CSS files and hashes their contents
- Generates an import map that maps clean URLs to hashed URLs
- Generates
<link rel="modulepreload">tags for all modules - Updates your HTML in place
The 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.
Usage
Add markers to your HTML:
<!-- IMPORTMAP -->
<!-- /IMPORTMAP -->
Run the CLI:
Or use as a library:
use ImportMap;
let map = scan?;
let html = read_to_string?;
if let Some = map.update_html
Output
The markers get replaced with:
<!-- IMPORTMAP -->
{
"imports": {
"/scripts/main.js": "/scripts/main.a1b2c3d4.js",
"/scripts/utils.js": "/scripts/utils.e5f6g7h8.js"
}
}
<!-- /IMPORTMAP -->
Your source files stay unchanged. The browser:
- Sees modulepreload → fetches all modules in parallel
- Sees
import "./utils.js"→ checks import map → requests./utils.a1b2c3d4.js - Gets a cache hit (already preloaded)
Server Setup
Your 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.
Details
- Hash: 8 hex chars from rapidhash of file contents
- Extensions:
.js,.mjs,.css - Skips: root-level
.jsfiles (service workers), files with.development.or.dev.in the name - Symlinks: followed (useful for
node_moduleslinks) - Indentation: preserved from the opening marker
License
MIT