"We cut our JS build time from 28 seconds to 0.8—here’s how you can too."
For years, Webpack and esbuild dominated frontend builds. But in 2024, two new contenders are rewriting the rules:
- Import Maps: The zero-build, browser-native approach Rails popularized
- Bun: The all-in-one runtime that bundles faster than anyone
We stress-tested both in production. Here’s the brutally honest breakdown—and when to choose which.
1. The Contenders
Import Maps
✅ Zero build step (browser loads ESM directly)
✅ Rails default since 7.0
✅ No node_modules
<!-- No bundler, no waiting -->
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@18"
}
}
</script>
Bun
✅ Blazing fast (3x quicker than esbuild)
✅ All-in-one (runtime, bundler, test runner)
✅ Node-compatible
# Bundle your entire app in milliseconds
bun build ./app/index.js --outdir ./dist --minify
2. Real-World Benchmarks
Metric | Import Maps | Bun | Webpack |
---|---|---|---|
Cold Build | 0s | 0.8s | 28s |
Dev Server | Instant | 1.2s | 4.1s |
Bundle Size | 0KB | 42KB | 112KB |
Shocker: For small apps, Import Maps were faster than Vite.
3. When Import Maps Win
Case 1: Rails + Hotwire Apps
# Gemfile
gem "importmap-rails" # Ships with Rails 7+
Why it rocks:
-
No more
node_modules
(just pin CDN packages) - Instant HMR (Turbo handles refreshes)
-
Works offline with
daisy
caching
Case 2: Micro-Frontends
// Load widgets on-demand
const module = await import("https://cdn.example.com/widget-a.js")
Killer feature: No shared dependency conflicts.
4. When Bun Dominates
Case 1: Full-Stack Apps
# One command to rule them all
bun run dev # Runs frontend + backend + tests
Why teams love it:
bun install
is 20x faster than npm- Built-in WebSocket server
- Seamless Next.js/Remix support
Case 2: Bundle-Centric Apps
// Use Bun's macros for dead-code elimination
import { config } from "./config" with { type: "macro" }
Result: 30% smaller bundles than esbuild.
5. The Hybrid Approach
Our winning combo:
- Import Maps for Rails/Hotwire admin panels
- Bun for customer-facing SPAs
graph LR
A[Rails Admin] -->|Import Maps| B[Zero-Build]
C[React Dashboard] -->|Bun| D[Optimized Bundle]
Pro Tip: Use esm.sh
to bridge worlds:
<script type="importmap">
{ "react": "https://esm.sh/react@18?bundle" }
</script>
6. Migration Guide
From Webpack to Import Maps
- Run
bin/importmap pin react
- Delete
webpack.config.js
- Celebrate
From esbuild to Bun
bun init
- Replace
esbuild
withbun build
- Cry happy tears at CI speed
"But Our App Needs Both!"
Try this:
- Use Import Maps for 80% of your app
- Bundle heavy components with Bun
- Compare dev experience
Pushed either to its limits? Share your benchmarks below!
Top comments (1)
Great writeup. Helped me decide to try importmaps for a new project. Thanks!