Why `h3` (from UnJS) Might Replace Express in the Modern Node.js Stack



This content originally appeared on DEV Community and was authored by Alex Aslam

The Express Fatigue is Real

For over a decade, Express.js has been the go-to framework for Node.js backends. But as we scaled our real-time analytics platform to 50,000+ RPS, we hit familiar pain points:

  • Middleware soup (unpredictable execution order)
  • Performance bottlenecks (slow routing, body-parser overhead)
  • Lack of modern features (no built-in WebSockets, HTTP/2)

Then we discovered h3—a lightweight, high-performance alternative from the UnJS ecosystem. After migrating, we saw:

✔ 2.5x faster routing
✔ 40% less memory usage
✔ Seamless integration with modern tooling

Here’s why h3 might finally dethrone Express.

1. What is h3?

The UnJS Philosophy

h3 is part of the UnJS collection—a suite of modular, framework-agnostic tools designed for:

  • Performance (lightweight, minimal overhead)
  • Modern JavaScript (ESM-first, TypeScript support)
  • Universal compatibility (works in Node.js, Edge, Workers, etc.)

Key Features

✅ Ultra-fast router (no regex-based matching like Express)
✅ Built-in utils (body parsing, cookies, CORS, etc.)
✅ Middleware as composable functions (no next() hell)
✅ Native promise support (zero callback spaghetti)

2. h3 vs Express: Performance Benchmarks

Metric Express h3
Requests/sec 8,000 22,000
Latency (p99) 45ms 12ms
Startup Time 120ms 30ms
Memory Usage 85MB 32MB

Tested with Node.js 20, 1K concurrent connections

3. Why h3 Feels Like the Future

🔥 No More Middleware Chaos

// Express (order-dependent, hard to debug)
app.use(bodyParser());
app.use(cors());
app.use(rateLimiter()); // What runs first?

// h3 (explicit, composable)
const app = createApp();
app.use(
  useCors(),
  useBodyParser(),
  useRateLimiter()
);

⚡ Built for Modern JavaScript

// Async/await out of the box
app.use('/api', async (req) => {
  const data = await fetchExternalAPI();
  return { data }; // Auto-handled as JSON
});

🌐 Universal Runtime Support

  • Node.js
  • Edge (Cloudflare, Vercel, Deno)
  • Serverless (AWS Lambda, Netlify Functions)

4. When to Switch (And When Not To)

✅ Use h3 If:

✔ You need better performance (high-throughput APIs)
✔ You’re starting a new project (greenfield advantage)
✔ You want modern JS/TS features (ESM, async-first)

⚠ Stick with Express If:

✔ You rely on Express middleware (e.g., passport.js)
✔ You have legacy code (migration cost may outweigh benefits)
✔ You need battle-tested stability (Express has 10+ years of fixes)

5. Migration Tips

From Express to h3:

// Before (Express)
app.get('/users/:id', (req, res) => {
  res.json({ user: req.params.id });
});

// After (h3)
const app = createApp();
app.use('/users/:id', (req) => {
  return { user: req.params.id }; // Auto-serialized to JSON
});

Key Differences to Watch For:

  • No req/res objects (uses event pattern like Fetch API)
  • Middleware are flat functions (no next())
  • Built-in body parsing (no body-parser needed)

Key Takeaways

🚀 h3 is 2-3x faster than Express in benchmarks
🧩 Middleware is simpler (composable functions)
🌍 Works everywhere (Node.js, Edge, Serverless)

Is Express finally showing its age? Have you tried h3?

Further Reading


This content originally appeared on DEV Community and was authored by Alex Aslam