Hono on Node vs Edge
Deploy the same Hono API on Node 24 or edge runtimes (Cloudflare Workers, Deno, Bun) with portability trade-offs.
Search across all documentation pages
Deploy the same Hono API on Node 24 or edge runtimes (Cloudflare Workers, Deno, Bun) with portability trade-offs.
Quick-reference portability pattern.
// shared app (runtime-agnostic)
import { Hono } from "hono";
export const app = new Hono();
app.get("/health", (c) => c.json({ ok: true }));
app.get("/users/:id", (c) => c.json({ id: c.req.param("id") }));
// Node entry: src/node.ts
import { serve } from "@hono/node-server";
import { app } from "./app.js";
serve({ fetch: app.fetch, port: 3000 });
// Cloudflare Worker entry: src/worker.ts
import { app } from "./app.js";
export default app;When to reach for this: APIs that must run on both traditional servers and edge/CDN for latency or multi-runtime strategy.
Portable app with runtime-specific adapters:
// app.ts - shared routes
import { Hono } from "hono";
import { cors } from "hono/cors";
export function createApp() {
const app = new Hono();
app.use("*", cors());
app.get("/api/status", (c) => c.json({ runtime: "hono" }));
return app;
}
// node.ts
import { serve } from "@hono/node-server";
import { createApp } from "./app.js";
const app = createApp();
serve({ fetch: app.fetch, port: Number(process.env.PORT ?? 3000) });
// worker.ts (Cloudflare)
import { createApp } from "./app.js";
export default createApp();
// wrangler.toml
// name = "my-api"
// main = "src/worker.ts"
// compatibility_date = "2024-01-01"What this demonstrates:
createApp() factory for all runtimes@hono/node-server; Workers export the app directly| Factor | Node 24 | Cloudflare Workers | Deno | Bun |
|---|---|---|---|---|
| Cold start | N/A (long-running) | < 5ms | Varies | Fast |
| CPU time limit | None | 30s (paid) | None | None |
| File system | Full | None (KV/R2) | Full | Full |
| TCP sockets | Yes | No (fetch only) | Yes | Yes |
| npm packages | All | Compatible subset | Deno registry | Most npm |
| Cost model | Server/pod | Per-request | Server | Server |
@hono/zod-validatorhono/jwtnode:fs, node:net direct usagefetch for I/O.process.env on Node, env binding on Workers. Fix: pass config into createApp(config).wrangler dev or Miniflare.| Alternative | Use When | Don't Use When |
|---|---|---|
| Node only (Fastify/Express) | Full Node API surface needed | Global edge latency is critical |
| Edge only (Workers) | Latency-sensitive, read-heavy | Heavy compute, TCP database |
| Hono portable | Need both with shared code | Single runtime is certain |
| Serverless (Lambda) | AWS ecosystem | Sub-millisecond cold start needed |
Node for full API features (DB TCP, file system, WebSockets). Workers for global latency on simple read endpoints.
Route logic yes. Database access, file I/O, and config need runtime-specific adapters.
Use HTTP-based drivers: @neondatabase/serverless, Supabase client, or Prisma with Accelerate.
Yes. Bun has native Hono support and fast startup. Good for dev and deployment if your ops supports Bun.
Test createApp() with Hono's app.request() (similar to Fastify inject). No port binding needed.
@hono/zod-openapi generates OpenAPI from Zod schemas. Works on all runtimes.
No. Edge compute runs logic close to users. Static caching is complementary. Use both.
Use the decision matrix in Framework Selection Checklist.
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.
Reviewed by Chris St. John·Last updated Jul 18, 2026