Tipps für die Portierung einer Express-App zu Hono
Wenn Sie eine Express-API betreuen und einen Umstieg auf Hono in Erwägung ziehen, sollten Sie zunächst eines verstehen: Dies ist keine Migration nach dem Suchen-und-Ersetzen-Prinzip. Express baut auf Nodes http-Modul und seinen eigenen req/res-Objekten auf. Hono hingegen basiert auf der Fetch API und Web Standards. Dieser Unterschied prägt alles: Routing, Middleware, Request-Handling und Responses.
Hier ist, was Sie vor dem Start wissen sollten.
Wichtige Erkenntnisse
- Express und Hono basieren auf grundlegend unterschiedlichen Fundamenten: Nodes
http-Modul gegenüber der Fetch API und Web Standards. - Hono ersetzt die separaten
req- undres-Objekte von Express durch ein einziges Kontextobjektc, und Handler müssen einResponsezurückgeben. - Die Middleware-Signaturen unterscheiden sich – Express verwendet
(req, res, next), während Hono(c, next)mit einem awaitetennext()nutzt. - Body Parsing findet direkt innerhalb der Hono-Handler statt, anstatt über globale Middleware.
- Eine inkrementelle Migration, beginnend mit zustandslosen JSON-Routen, ist deutlich sicherer als ein kompletter Rewrite.
Verstehen Sie zuerst den architektonischen Unterschied
Express umhüllt Nodes IncomingMessage und ServerResponse. Jedes req- und res-Objekt ist Node-spezifisch. Hono hingegen arbeitet mit standardisierten Request- und Response-Objekten – denselben, die Sie in einem Browser oder einem Cloudflare Worker verwenden würden.
Wenn Sie Hono unter Node.js ausführen, nutzen Sie den @hono/node-server-Adapter, der diese Lücke überbrückt. Der Handler selbst bleibt jedoch laufzeitunabhängig.
// Express
app.get('/users/:id', async (req, res) => {
const user = await db.findById(req.params.id)
res.json(user)
})
// Hono
app.get('/users/:id', async (c) => {
const user = await db.findById(c.req.param('id'))
return c.json(user)
})
Die Struktur ist ähnlich, aber c (das Kontextobjekt) ersetzt sowohl req als auch res. Sie geben ein Response zurück, anstatt Methoden auf res aufzurufen.
Migration von Node.js-APIs zu Hono: Beginnen Sie mit zustandslosen Routen
Der sicherste Einstieg beim Portieren von Express-Apps zu Hono sind zustandslose, reine JSON-Routen – kein Dateisystemzugriff, keine Node-spezifischen Streams, keine Session-Middleware. Diese lassen sich sauber übertragen.
Routen, die von Node-spezifischen APIs abhängen (req.socket, res.locals, res.sendFile), erfordern mehr Überlegung. Isolieren Sie diese zuerst, damit Sie wissen, womit Sie es zu tun haben, bevor Sie sich auf eine vollständige Migration einlassen.
Discover how at OpenReplay.com.
Hono-Middleware-Migration: Keine Kompatibilität voraussetzen
Express-Middleware folgt dem Muster (req, res, next). Hono-Middleware verwendet (c, next) und ruft typischerweise await next() auf. Sie sind nicht austauschbar.
// Express middleware
app.use((req, res, next) => {
req.startTime = Date.now()
next()
})
// Hono equivalent
app.use(async (c, next) => {
c.set('startTime', Date.now())
await next()
})
Für gängige Pakete bietet Hono offizielle Entsprechungen:
| Express | Hono-Entsprechung |
|---|---|
cors() | hono/cors |
helmet() | hono/secure-headers |
express.json() | Integriert über c.req.json() |
morgan | hono/logger oder eine eigene Middleware |
Schreiben Sie Middleware bewusst neu, anstatt zu versuchen, Express-Middleware zu wrappen – die Abstraktion hält selten sauber stand.
Request Body und Response Handling
In Express 5 erfolgt das Body Parsing weiterhin über Middleware. In Hono parsen Sie den Body direkt im Handler:
// Hono body parsing
app.post('/items', async (c) => {
const body = await c.req.json()
return c.json({ received: body }, 201)
})
Responses werden stets zurückgegeben, niemals mutiert. Es gibt kein res.status(201).json(...) – stattdessen übergeben Sie den Status als zweites Argument an c.json().
Fehlerbehandlung
Express verwendet einen Fehlerhandler mit vier Argumenten: (err, req, res, next). Hono nutzt app.onError:
app.onError((err, c) => {
console.error(err)
return c.json({ error: 'Internal Server Error' }, 500)
})
Inkrementell migrieren, nicht auf einen Schlag
Ein vollständiger Rewrite läuft selten reibungslos ab. Ein besserer Ansatz:
- Portieren Sie jeweils eine isolierte Routengruppe.
- Lassen Sie Hono während des Übergangs parallel zu Express laufen.
- Schreiben Sie Middleware explizit neu – wrappen Sie sie nicht.
- Heben Sie Node-spezifische Abhängigkeiten (Dateiverarbeitung, Legacy-Authentifizierung) bis zum Schluss auf.
Fazit
Das Portieren von Express-Apps zu Hono ist unkompliziert, sobald man akzeptiert, dass die beiden Frameworks auf unterschiedlichen Grundlagen ruhen. Die Routing-Syntax ist vertraut genug, sodass die meisten Routen in wenigen Minuten übersetzt werden können. Die eigentliche Arbeit liegt in der Middleware und allem, was direkt Node-spezifische APIs berührt. Gehen Sie diese Aspekte bewusst an, dann wird die Migration handhabbar.
FAQs
Ja. Ein gängiges Muster besteht darin, einen Reverse Proxy oder einen kleinen Node-Einstiegspunkt vor beide zu schalten, der bestimmte Pfade an die Hono-App weiterleitet und den Rest bei Express belässt. So können Sie Routengruppen nacheinander migrieren und bei Problemen schnell zurückrollen, anstatt sich auf einen einzigen riskanten Cutover festzulegen.
Hono läuft unter Node.js, Bun, Deno, Cloudflare Workers, AWS Lambda und mehreren weiteren Laufzeitumgebungen. Unter Node nutzen Sie den @hono/node-server-Adapter, um das Fetch-API-Modell mit Nodes http-Modul zu verbinden. Derselbe Handler-Code bleibt über alle Laufzeiten hinweg portabel – einer der Hauptvorteile von Hono gegenüber Express.
Im Allgemeinen nein. Express-Middleware hängt von Nodes req- und res-Objekten sowie dem next-Callback ab, während Hono-Middleware auf einem Fetch-artigen Kontext arbeitet. Es existieren einige Community-Adapter, diese sind jedoch tendenziell instabil. Der empfohlene Ansatz ist, Middleware gegen Honos API neu zu schreiben, da die meisten gängigen Anforderungen bereits offizielle oder integrierte Entsprechungen haben.
Hono ist im Allgemeinen schneller als Express, insbesondere bei Routing und JSON-Responses, dank seines schlanken Routers und des Fetch-basierten Designs. Reale Performance-Gewinne hängen von Ihrer Workload ab – Datenbankabfragen und externe Aufrufe dominieren in der Regel. Betrachten Sie Performance als nützlichen Nebeneffekt der Migration, nicht als Hauptgrund, es sei denn, Ihre Benchmarks zeigen, dass Routing-Overhead ein echter Engpass ist.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.