The server runtime/The server runtime

The server runtime

A map of the two halves: the live Nitro server, and the Hono contract.

The server runtime is two chapters

“The server” in BionicJS is not one thing, and the two halves have different names, different maturity, and different documentation. This chapter is the map. The two chapters it points to carry the detail.

Nitro and h3Hono and the RPC contract
QuestionWhat actually serves a request?How does the browser learn what the endpoints are?
StatusLive. Every request goes through it.Generated, not yet mounted.
Projectsnitropackhono
You writeserver/api/*.tsNothing. It is generated.
ⓘ
If you just want an endpoint, read Nitro and h3. If you are deciding whether to bet on the typed client, read Hono and the RPC contract - including the part where it does not work yet.

The short version

A request arrives at /api/anything. Vite proxies it to Nitro. Nitro matches it against a file in server/api/ and calls that file’s h3 handler. There is no Hono in that path, and there is no custom router anywhere.

server/api/health.ts
1import { defineEventHandler } from "h3";
2
3export default defineEventHandler(() => ({
4  status: "ok",
5}));

Separately, @bionicjs/dev reads the same server/api tree and writes a Hono router to .bionicjs/hono.ts, plus a typed client in .bionicjs/api-client.ts. That client is the missing half of the story: nothing mounts the router, so the file-based API is fully functional while the generated client is inert.

Who owns what

LayerRoleVisible to you?
NitroServer runtime, build, and deploy presetsNo - an implementation detail
h3The handler shape, via defineEventHandlerShape only, as a standard API
HonoA generated router type and hc clientNot yet - it is not mounted
server/api/*Your endpointsYes - this is what you write
ⓘ
Older revisions of these docs described Hono as the server running inside Nitro, and then as purely a client-side type contract. Both descriptions were wrong in a way that mattered. Hono is a third independent project; today it is generated but unconnected, and the live server path is Nitro plus h3.

Why it is split this way

The split exists because the two problems are genuinely different.h3 gives a portable server: an event object, status codes, headers, cookies, streaming, and no Node types in the way. Hono contributes the one thing h3 has nothing to do with - a router type that can be shared with the browser.

Keeping them separate means the server half works on its own, which is why /api/health returns 200 today even though the typed client is incomplete. The open question is whether the client half should be built on Hono at all.

  • server/api/*.ts is the surface you write, and it does not change either way.
  • The server runtime is Nitro + h3. That is settled.
  • Hono’s future is genuinely undecided - treat any Hono example you find as aspirational until the router is mounted.