RouteGraph v1.0.0 is out. It's stable, it's typed, it's not going to rewrite your framework of choice into a decorator soup. → Try it in 90 seconds

Benchmarks

Every framework’s landing page has a chart where their green bar is enormous and everyone else’s bar is sad and gray. We were fully prepared to make that chart. We even picked the shade of green.

Then we actually looked at what RouteGraph does at request time, and it turned out to be too boring to lie about.

⚠️

What follows is two real, structural, checkable-in-the-source-code charts — not a req/sec number from a laptop with fourteen Chrome tabs open. If you came here for a fabricated 400% speedup, we’re sorry, and also not sorry.

The one honest chart

RouteGraph’s adapters do not sit in front of your handler doing reflection, proxying, or anything clever. At startup, RouteGraph.load() scans routes/ once and dynamically imports each matching file. At request time, an adapter looks up the already-loaded route and calls your handler directly. That’s the entire hot path.

Function calls in the hot path
Request arrives → … → your handler runs. Counted, not benchmarked.
12Express12Hono12Fastify12Elysia12Koa
raw framework router+ RouteGraph adapter
We didn't rent a c6i.8xlarge and run 10,000 warmup iterations for this one. We read the adapter source: lookup(method, path) → handler(req, res). One extra call, forever — whether you have 6 routes or 6,000. That's the whole benchmark.

There is no scenario where this number goes up as your app grows — it isn’t measuring speed, it’s measuring architecture. A router with 6 routes and a router with 6,000 routes both add exactly one function call.

The chart that’s actually about you

The real cost RouteGraph removes was never in the request path. It was in your hands, every time you added an endpoint.

Lines of routing code you hand-maintain
As the number of endpoints grows — one dot per file you'd otherwise write in a router.
010203040500 endpoints50 endpointsmanual router: 50 linesRouteGraph: 0 lines
"0" isn't rounding. Adding a route is adding a file — the routing table is the filesystem. There is no registration step to forget, and nothing here to keep "in sync."

Fifty endpoints is fifty lines of router.get(...) you had to write, keep correctly ordered, and not typo. RouteGraph’s line count for the same fifty endpoints is the same as its line count for zero: none. The routing table is the filesystem.

What we’re not going to claim

  • That RouteGraph makes Express faster. Express is exactly as fast as Express. We call it the same way you would.
  • That switching from Fastify to Elysia gives you a “10x” anything. It gives you Elysia’s performance characteristics, because that’s whose request loop is now running. We’re a routing layer, not a physics engine.
  • That this page has ever been A/B tested against a version with a bigger green bar. (It has not. We thought about it. We’re telling you that because the alternative was making the number up, and the README already promises we don’t do that.)

If you want real numbers

Profile your own handlers with your own payloads on your own hardware — that’s the only benchmark that was ever going to be true for your API. RouteGraph’s contribution to that number is the one constant in the chart above.