Come mai mi sono innamorato di Hono
Ho scritto API in Express per anni. Era il punto di partenza ovvio per chiunque venisse dal mondo Node.js: ecosistema enorme, documentazione ovunque, middleware per qualsiasi cosa. Poi è arrivato Fastify con la sua ossessione per le performance e il suo sistema di schema validation — un salto di qualità reale.
Poi ho provato Hono per un progetto piccolo, quasi per caso, e non sono più tornato indietro.
Cos’è Hono
Hono è un framework web ultraleggero scritto in TypeScript. Il nome viene dal giapponese 炎 — fiamma. È veloce, è piccolo, e gira ovunque: Node.js, Deno, Bun, Cloudflare Workers, Vercel Edge Functions, AWS Lambda.
Questa ultima parte è quella che fa la differenza.
Il problema che Hono risolve
Express e Fastify sono legati a Node.js. Funzionano benissimo su un server, ma non girano su runtime edge come Cloudflare Workers o Vercel Edge Functions — ambienti che usano le Web API standard invece delle API di Node.
Se volevi logica server-side su edge, dovevi riscrivere tutto con API diverse, imparare i quirk di ogni piattaforma, tenere codebase separate.
Hono è costruito sulle Web Standard API — Request, Response, Headers, URL. Quelle che il browser conosce già. Quelle che ogni runtime moderno implementa.
import { Hono } from "hono";
const app = new Hono();
app.get("/api/hello", (c) => {
return c.json({ message: "ciao" });
});
export default app;
Questo codice gira identico su Node.js, Bun, Cloudflare Workers e Vercel Edge. Zero modifiche.
Quello che mi ha convinto davvero
La type safety è di prima classe
Con Express, i tipi erano un’aggiunta — @types/express era un pacchetto separato, i middleware rompevano il type inference a ogni passaggio. Con Hono, TypeScript è al centro del design.
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
const app = new Hono();
const schema = z.object({
name: z.string().min(1),
age: z.number().int().positive(),
});
app.post("/utenti", zValidator("json", schema), (c) => {
const { name, age } = c.req.valid("json"); // tipizzato, senza cast
return c.json({ name, age }, 201);
});
Il tipo di c.req.valid("json") è inferito direttamente dallo schema Zod. Se il payload non valida, Hono risponde con 400 prima ancora di entrare nel handler. Nessuna logica di validazione da scrivere a mano.
Il middleware è componibile senza magia
In Express il middleware era una funzione con quattro argomenti e next() da chiamare al momento giusto — un contratto implicito che portava a bug sottili. In Hono è una funzione asincrona che usa await next() in modo esplicito e leggibile:
// Middleware di autenticazione
app.use("/api/*", async (c, next) => {
const token = c.req.header("Authorization");
if (!token) return c.json({ error: "non autorizzato" }, 401);
await next();
});
Il client RPC è una cosa bellissima
Questa feature da sola vale il cambio. Hono permette di esportare i tipi delle route e usarli in un client TypeScript — senza generare codice, senza OpenAPI, senza passaggi intermedi.
// server.ts
const routes = app
.get("/posts/:id", (c) => {
return c.json({ id: c.req.param("id"), title: "Post di esempio" });
});
export type AppType = typeof routes;
// client.ts
import { hc } from "hono/client";
import type { AppType } from "./server";
const client = hc<AppType>("http://localhost:3000");
const res = await client.posts[":id"].$get({ param: { id: "42" } });
const data = await res.json(); // tipizzato end-to-end
TypeScript sa già cosa ritorna ogni endpoint. Se cambi il tipo sul server, il client rompe a compile time — non a runtime in produzione.
Dove lo uso
Oggi uso Hono per qualsiasi cosa che sia una API o un backend leggero:
- API deployate su Cloudflare Workers (edge, latenza globale sotto 50ms)
- Webhook handler su AWS Lambda
- Backend di prototipi e side project su Bun in locale
Per applicazioni con ORM complessi, job queue, socket — valuto caso per caso. Ma per API stateless, Hono è diventato il mio default.
Conclusione
Express mi ha insegnato come funziona un framework web. Fastify mi ha mostrato che le performance si possono progettare. Hono mi ha fatto capire che il runtime non dovrebbe essere un vincolo architetturale.
È un framework che rispetta il tuo tempo: TypeScript funziona senza configurazione, la documentazione è chiara, le API sono prevedibili. Non ti sorprende mai nel modo sbagliato.
E questo, alla fine, è tutto quello che chiedo a uno strumento.