Hono on Node vs Edge
Deploy the same Hono API on Node 24 or edge runtimes (Cloudflare Workers, Deno, Bun) with portability trade-offs.
Recipe
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.
Working Example
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:
- Shared
createApp()factory for all runtimes - Node uses
@hono/node-server; Workers export the app directly - CORS and routes are runtime-agnostic
- Environment config differs per deployment target
Deep Dive
Runtime Comparison
| 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 |
What Portes Cleanly
- Route definitions and middleware
- JSON request/response handling
- Zod validation via
@hono/zod-validator - JWT auth via
hono/jwt - CORS and security headers
What Does Not Port
node:fs,node:netdirect usage- Native database drivers (use HTTP-based or edge-compatible)
- Long-running background tasks
- WebSocket (limited on Workers; use Durable Objects)
Gotchas
- Using Node-only APIs in shared code - breaks on Workers. Fix: abstract behind adapters; use
fetchfor I/O. - PostgreSQL driver on edge - TCP not available on Workers. Fix: use Neon serverless driver, Supabase HTTP, or Prisma Accelerate.
- Assuming unlimited CPU - Workers have CPU time limits. Fix: keep handlers fast; offload heavy work to queues.
- Environment variables differ -
process.envon Node,envbinding on Workers. Fix: pass config intocreateApp(config). - No persistent connections on edge - each request is isolated. Fix: use Durable Objects or external state store.
- Testing only on Node - edge runtime surprises in production. Fix: test with
wrangler devor Miniflare.
Alternatives
| 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 |
FAQs
Should I run Hono on Node or Workers?
Node for full API features (DB TCP, file system, WebSockets). Workers for global latency on simple read endpoints.
Can I share 100% of code between Node and edge?
Route logic yes. Database access, file I/O, and config need runtime-specific adapters.
How do I connect to PostgreSQL from Workers?
Use HTTP-based drivers: @neondatabase/serverless, Supabase client, or Prisma with Accelerate.
Is Bun a good Hono runtime?
Yes. Bun has native Hono support and fast startup. Good for dev and deployment if your ops supports Bun.
How does this affect testing?
Test createApp() with Hono's app.request() (similar to Fastify inject). No port binding needed.
What about OpenAPI on Hono?
@hono/zod-openapi generates OpenAPI from Zod schemas. Works on all runtimes.
Does edge deployment replace CDN caching?
No. Edge compute runs logic close to users. Static caching is complementary. Use both.
How do I decide Node vs edge?
Use the decision matrix in Framework Selection Checklist.
Related
- Hono Basics - getting started
- Serverless Basics - serverless patterns
- Cold Start Mitigation - edge cold starts
- Framework Selection Checklist - full matrix
- Lightweight Frameworks Best Practices - section 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.