The architecture of Hono, x-rayed
Hono is the biggest x-ray in this gallery — 307 components — attached to the smallest dependency list: zero. Everything a web framework needs (routers, middleware, a JSX engine, validation helpers, a typed RPC client) is implemented in-tree on web standards, which is exactly what lets one codebase run on Cloudflare Workers, Deno, Bun, and Node unchanged.
archsteer xray v0.4.1 against honojs/hono@d6b1d32 (src/) on 2026-07-05. Read-only static analysis — no code executed, no architecture rules declared. Structure, not judgment.Module dependency graph
Top 14 modules by connectivity; an arrow means "imports from".
graph LR
m0["adapter"]
m1["client"]
m2["context"]
m3["helper"]
m4["hono"]
m5["hono-base"]
m6["hono.test"]
m7["http-exception"]
m8["middleware"]
m9["request"]
m10["router"]
m11["types"]
m12["utils"]
m13["validator"]
m0 --> m2
m0 --> m3
m0 --> m4
m0 --> m7
m0 --> m8
m0 --> m11
m0 --> m12
m1 --> m0
m1 --> m4
m1 --> m5
m1 --> m10
m1 --> m11
m1 --> m12
m1 --> m13
m2 --> m9
m2 --> m10
m2 --> m11
m2 --> m12
m3 --> m1
m3 --> m2
m3 --> m4
m3 --> m5
m3 --> m7
m3 --> m8
m3 --> m9
m3 --> m10
m3 --> m11
m3 --> m12
m3 --> m13
m4 --> m5
m4 --> m10
m4 --> m11
m5 --> m2
m5 --> m10
m5 --> m11
m5 --> m12
m6 --> m1
m6 --> m2
m6 --> m4
m6 --> m7
m6 --> m8
m6 --> m10
m6 --> m11
m6 --> m12
m7 --> m12
m8 --> m2
m8 --> m3
m8 --> m4
m8 --> m7
m8 --> m10
m8 --> m11
m8 --> m12
m9 --> m7
m9 --> m10
m9 --> m11
m9 --> m12
m10 --> m12
m11 --> m2
m11 --> m5
m11 --> m12
m12 --> m3
m12 --> m9
m13 --> m2
m13 --> m3
m13 --> m4
m13 --> m7
m13 --> m9
m13 --> m11
m13 --> m12Components by module
Most connected components
Top 20 of 307 by exported API surface and dependency count.
| Component | Module | Key exports |
|---|---|---|
jsx/hooks/index.ts | jsx | STASH_EFFECT, startViewTransition, useViewTransition, startTransition |
jsx/base.ts | jsx | getNameSpaceContext, booleanAttributes, JSXNode, JSXFragmentNode |
jsx/dom/intrinsic-element/components.ts | jsx | clearCache, composeRef, title, script |
jsx/dom/render.ts | jsx | buildDataStack, getNameSpaceContext, build, buildNode |
adapter/aws-lambda/handler.ts | adapter | streamHandle, handler, handler, handle |
jsx/intrinsic-element/components.ts | jsx | title, script, style, link |
helper/ssg/ssg.ts | helper | DEFAULT_OUTPUT_DIR, defaultExtensionMap, combineBeforeRequestHooks, combineAfterResponseHooks |
middleware/combine/index.ts | middleware | some, every, except |
helper/css/common.ts | helper | PSEUDO_GLOBAL_SELECTOR, isPseudoGlobalSelectorRe, DEFAULT_STYLE_ID, SELECTOR |
middleware/jwt/jwt.ts | middleware | jwt, verifyWithJwks, verify, decode |
utils/jwt/types.ts | utils | JwtAlgorithmNotImplemented, JwtAlgorithmRequired, JwtAlgorithmMismatch, JwtTokenInvalid |
middleware/jwk/index.test.ts | middleware | — |
utils/jwt/jwt.ts | utils | isTokenHeader, sign, verify, verifyWithJwks |
middleware/language/language.ts | middleware | DEFAULT_OPTIONS, parseAcceptLanguage, normalizeLanguage, detectFromQuery |
jsx/streaming.ts | jsx | StreamingContext, Suspense, renderToReadableStream |
hono.test.ts | hono.test | — |
utils/url.ts | utils | splitPath, splitRoutingPath, getPattern, tryDecode |
helper/css/index.ts | helper | createCssContext, css, cx, keyframes |
hono-base.ts | hono-base | — |
jsx/components.ts | jsx | childrenToString, ErrorBoundary |
What the structure teaches
Zero dependencies is the architecture
Not a small dependency list — literally none. By building only on Web Standard APIs (Request, Response, URL), Hono makes the platform the dependency. The adapter/ package then contains the only code that knows whether it's running on Workers, Deno, Bun, AWS Lambda, or Node.
There's an entire JSX runtime in here
The jsx/ subsystem — including hooks, a DOM renderer, and intrinsic element types — is the largest part of the graph, bigger than the routing core. Hono quietly ships a React-compatible UI layer so server-rendered components need no external view library.
Routers are swappable strategies
router/ contains multiple complete implementations — RegExpRouter, TrieRouter, SmartRouter, LinearRouter — behind one interface. SmartRouter picks the fastest at registration time. It's the strategy pattern applied to the hottest code path a framework has.
X-ray your own repo
This page is unedited archsteer xray output plus commentary. The same map of your codebase takes one command, runs locally, and never sends code anywhere: pip install archsteer && archsteer xray
FAQ
How is Hono structured internally?
As a zero-dependency TypeScript codebase of 307 components: a small core (hono-base, context, request), swappable router implementations behind one interface, a middleware/ collection, per-platform glue in adapter/, helper/ utilities, a typed RPC client, and a complete JSX runtime with hooks and a DOM renderer.
How does Hono run on so many runtimes?
The core only uses Web Standard APIs — Request, Response, URL, Headers — that every modern runtime implements. Platform differences (env bindings on Workers, serve() on Deno/Bun/Node, event shapes on Lambda) are confined to small files in adapter/, so the other ~290 components are runtime-agnostic by construction.
How was this architecture map generated?
By running `archsteer xray` (an open-source, MIT-licensed CLI) against the src/ directory of the public GitHub repo — read-only static analysis, no code executed. Reproduce it with `pip install archsteer && archsteer xray`.
More x-rays
The architecture of FastAPI, x-rayed
An auto-generated architecture map of FastAPI: 48 components across 28 modules, the module…
The architecture of Flask, x-rayed
An auto-generated architecture map of Flask: 24 components, the sansio core split, bluepri…
The architecture of HTTPX, x-rayed
An auto-generated architecture map of HTTPX: 23 underscore-private components, the pluggab…
The architecture of Starlette, x-rayed
An auto-generated architecture map of Starlette: 34 components, the middleware stack, and …