Moderne TypeScript-Backends: Hono, ElysiaJS und was nach NestJS kommt
Ehrlicher Vergleich von Hono, ElysiaJS und NestJS aus der Produktion. DX, Performance, Middleware, ORM-Auswahl, Deployment-Flexibilität und wann welches Framework passt.
Warum wir neue Projekte nicht mehr mit NestJS starten
NestJS ist ein großartiges Framework. Wir haben Enterprise-Systeme damit gebaut (Vendure ist unter der Haube NestJS, und wir lieben Vendure). Aber für neue, eigenständige Backend-Services sind wir zu Hono gewechselt. Nicht weil NestJS schlecht ist. Weil Hono besser zu unserer Arbeitsweise passt.
Der Wechsel passierte schrittweise. Wir starteten einen neuen API-Service, überlegten NestJS zu nehmen und fragten uns: Brauchen wir Decorators, Modules, Provider und den Angular-inspirierten Dependency-Injection-Container für eine API mit 15 Endpoints? Die Antwort war nein. Wir brauchten ein schnelles HTTP-Framework, das auf jeder Runtime läuft, gute TypeScript-Unterstützung bietet und keine Architektur vorschreibt.
Hono hat das geliefert. Dann haben wir ElysiaJS auf Bun für einen Performance-kritischen Service ausprobiert. Das hat etwas anderes geliefert. Dieser Artikel ist ein ehrlicher Vergleich von jemandem, der alle drei in Produktion betreibt.
Für breiteren Kontext zu unserer Herangehensweise an Software Engineering behandelt dieser Guide unsere Prinzipien. Wie diese Frameworks in Commerce-Architekturen passen, findest du in unserem Vendure-Produktionsguide.
Die drei Frameworks
| Feature | NestJS | Hono | ElysiaJS |
|---|---|---|---|
| Runtime | Node.js | Node, Bun, Deno, Cloudflare Workers, Lambda, Vercel | Bun (primär) |
| Architektur | Opinionated (Modules, Controller, Provider) | Minimal (Routes, Middleware) | Minimal (Routes, Plugins) |
| Typsicherheit | Decorators + Runtime-Validierung | Middleware-basiert, manuell | Eingebaut (TypeBox) |
| DI-Container | Eingebaut (Angular-Stil) | Keiner (bring your own) | Keiner (Plugins) |
| Bundle-Größe | Groß (~50MB node_modules) | Winzig (~14KB Core) | Klein (~2MB mit Bun) |
| Cold Start | Langsam (2-5s auf Lambda) | Schnell (< 100ms auf Lambda) | Schnell (< 50ms auf Bun) |
| Middleware-Ökosystem | Groß (passport, class-validator, etc.) | Wachsend (auth, cors, jwt, etc.) | Wachsend (swagger, jwt, etc.) |
| Lernkurve | Steil (Modules, Decorators, DI, Guards, Pipes) | Minimal (Express-ähnlich) | Minimal (Express-ähnlich mit Validierung) |
| Am besten für | Große Enterprise-Apps, Vendure Plugins | Multi-Runtime-APIs, Edge Functions, Microservices | Bun-native Hochleistungs-APIs |
Hono: Das Framework, das überall läuft
Hono ist ein Web-Framework, gebaut für die Edge. Es läuft auf Node.js, Bun, Deno, Cloudflare Workers, AWS Lambda, Vercel Edge und Fastly. Derselbe Code deployt auf jede Runtime ohne Änderungen.
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { jwt } from 'hono/jwt';
import { logger } from 'hono/logger';
const app = new Hono();
// Middleware
app.use('*', logger());
app.use('*', cors({ origin: ['https://app.example.com'] }));
app.use('/api/*', jwt({ secret: process.env.JWT_SECRET! }));
// Routen
app.get('/api/products', async (c) => {
const products = await productService.findAll();
return c.json({ data: products });
});
app.get('/api/products/:id', async (c) => {
const product = await productService.findById(c.req.param('id'));
if (!product) return c.json({ error: 'Not found' }, 404);
return c.json({ data: product });
});
app.post('/api/products', async (c) => {
const body = await c.req.json();
const product = await productService.create(body);
return c.json({ data: product }, 201);
});
export default app;
Warum wir es mögen
Runtime-Portabilität. Wir deployen dieselbe Hono-Codebasis auf Lambda (API Gateway), Bun (Container) und Cloudflare Workers (Edge). Keine Code-Änderungen zwischen Runtimes. Das ist Honos einzigartige Stärke. Kein anderes Framework kann das.
14KB Core. Cold Starts auf Lambda sind unter 100ms. NestJS Cold Starts liegen bei 2-5 Sekunden. Für Serverless-Deployments ist dieser Unterschied die komplette User Experience.
Keine Architektur-Vorgaben. Hono gibt dir Routing, Middleware und Context. Du entscheidest, wie du Services, Repositories und Business-Logik strukturierst. Für kleine bis mittlere APIs (5-50 Endpoints) ist das genau richtig. Du brauchst kein Modul-System für 20 Routen.
tRPC-Integration. Wir nutzen Hono + tRPC für reine TypeScript-Stacks. End-to-End-Typsicherheit vom Server zum Client ohne GraphQL:
import { trpcServer } from '@hono/trpc-server';
import { appRouter } from './trpc/router';
app.use('/trpc/*', trpcServer({ router: appRouter }));
Wo es Schwächen hat
Kein eingebautes DI. Für große Anwendungen mit 50+ Services und komplexen Dependency Graphs musst du einen eigenen DI-Container mitbringen (tsyringe, inversify) oder Dependencies manuell verdrahten. Für kleine Services ist das in Ordnung. Für große wird es mühsam.
Kleineres Middleware-Ökosystem. NestJS hat passport, class-validator, class-transformer, swagger und Hunderte Community-Pakete. Honos Ökosystem wächst, ist aber noch nicht auf dem Level. Du wirst mehr Custom-Middleware schreiben.
Keine Konventionen für große Apps. NestJS Modules geben dir eine Struktur, die auf 100+ Dateien skaliert. Hono schreibt keine Struktur vor. Für Teams mit Junior-Entwicklern kann das Fehlen von Konventionen zu inkonsistenten Codebasen führen.
ElysiaJS: Wenn Bun-Performance zählt
ElysiaJS ist speziell für Bun gebaut. Es nutzt Buns native APIs, FFI-Bindings und den optimierten HTTP-Server, um Performance zu erreichen, die Node.js-Frameworks nicht bieten können.
import { Elysia, t } from 'elysia';
import { swagger } from '@elysiajs/swagger';
import { jwt } from '@elysiajs/jwt';
const app = new Elysia()
.use(swagger())
.use(jwt({ name: 'jwt', secret: process.env.JWT_SECRET! }))
.get('/products', async () => {
return productService.findAll();
})
.post('/products', async ({ body }) => {
return productService.create(body);
}, {
body: t.Object({
name: t.String(),
price: t.Number({ minimum: 0 }),
description: t.Optional(t.String()),
}),
})
.listen(3000);
Warum es interessant ist
Eingebaute Validierung mit TypeBox. Schemas werden inline definiert und generieren automatisch OpenAPI-Docs. Keine separate Validierungsbibliothek nötig. Die Types fließen vom Schema zum Handler bis zur Response.
Bun-native Performance. ElysiaJS auf Bun bewältigt 2-3x mehr Requests pro Sekunde als Express auf Node.js bei einfachen JSON-APIs. Für compute-leichte, I/O-lastige Workloads (die meisten APIs) ist der Unterschied weniger dramatisch, aber messbar.
End-to-End Type Inference. Der Request-Body-Typ wird aus dem TypeBox-Schema abgeleitet. Der Response-Typ wird aus dem Handler abgeleitet. Der Client kann Eden (ElysiaJS' tRPC-ähnlicher Client) für typsichere API-Aufrufe nutzen.
Wo es Schwächen hat
Nur Bun. Wenn du auf Node.js, Lambda oder Cloudflare Workers deployen musst, ist ElysiaJS keine Option. Bun ist produktionsreif, aber nicht universell in allen Hosting-Umgebungen unterstützt.
Kleineres Ökosystem. Buns Paketkompatibilität ist gut, aber nicht 100%. Manche Node.js-Pakete nutzen native Addons, die Bun nicht unterstützt. Datenbanktreiber, Bildverarbeitungsbibliotheken und native Crypto-Module können problematisch sein.
Weniger praxiserprobt. Bun und ElysiaJS sind neuer. Die Community ist kleiner. Wenn du auf einen Edge Case stößt, gibt es weniger Stack-Overflow-Antworten und weniger Leute, die das gleiche Problem schon gelöst haben.
Drizzle vs Prisma vs TypeORM: Die ORM-Realität
Die Framework-Wahl ist die halbe Entscheidung. Die ORM-Wahl ist die andere Hälfte.
| Feature | Drizzle | Prisma | TypeORM |
|---|---|---|---|
| Query-Stil | SQL-ähnlich (explizit) | Client API (generiert) | Active Record oder Data Mapper |
| Typsicherheit | Exzellent (aus Schema abgeleitet) | Exzellent (generierter Client) | Gut (Decorators) |
| Migration | SQL-basiert, manuelle Kontrolle | Auto-generiert, verwaltet | Auto-generiert oder manuell |
| Performance | Schnell (dünner Wrapper über SQL) | Gut (Query Engine) | Moderat (schwere Abstraktion) |
| Raw SQL | Erstklassig (sql`` Template) | Möglich, aber umständlich | Möglich via Query Builder |
| Edge/Serverless | Funktioniert (leichtgewichtig) | Braucht Prisma Accelerate für Edge | Zu schwer für Edge |
| Lernkurve | Niedrig (wenn du SQL kannst) | Niedrig (API-Docs sind exzellent) | Mittel (Decorators, Relations) |
| Bundle-Größe | Klein (~500KB) | Groß (~15MB mit Engine) | Mittel (~5MB) |
| Am besten mit | Hono, ElysiaJS | Jedem Framework | NestJS, Vendure |
Unsere Stack-Entscheidungen
Hono + Drizzle + tRPC: Für neue TypeScript-APIs. Leichtgewichtig, schnell, End-to-End typsicher. Drizzles SQL-ähnliche Syntax gibt uns explizite Kontrolle über Queries ohne den Abstraktions-Overhead von TypeORM oder den Engine-Overhead von Prisma.
// Drizzle: SQL-ähnlich, explizit, typsicher
const products = await db
.select()
.from(productsTable)
.where(and(
eq(productsTable.tenantId, tenantId),
eq(productsTable.status, 'active'),
gt(productsTable.price, 1000),
))
.orderBy(desc(productsTable.createdAt))
.limit(20);
NestJS + TypeORM: Für Vendure-Plugins und große Enterprise-Anwendungen, bei denen das Modul-System und der DI-Container ihr Gewicht rechtfertigen. TypeORM integriert sich tief in NestJS und Vendure.
Prisma: Wenn wir auto-generierte Migrationen brauchen und das Team Prismas Dokumentation und Developer Experience gegenüber direkter Query-Kontrolle bevorzugt.
Deployment-Flexibilität
Hier hat die Framework-Wahl den größten praktischen Einfluss.
| Deployment-Ziel | NestJS | Hono | ElysiaJS |
|---|---|---|---|
| Docker/Kubernetes | Funktioniert | Funktioniert | Funktioniert (Bun-Image) |
| AWS Lambda | Langsame Cold Starts (2-5s) | Schnell (< 100ms) | Nicht unterstützt |
| Cloudflare Workers | Nicht unterstützt | Läuft nativ | Nicht unterstützt |
| Vercel Edge | Nicht unterstützt | Läuft nativ | Nicht unterstützt |
| Deno Deploy | Nicht unterstützt | Läuft nativ | Nicht unterstützt |
| Traditioneller VPS | Funktioniert | Funktioniert | Funktioniert (braucht Bun) |
| Bun nativ | Teilweise (meiste NestJS-Apps laufen auf Bun) | Funktioniert | Nativ, optimiert |
Wenn du nur auf Container deployest, funktionieren alle drei. Wenn du auf Serverless oder Edge deployest, ist Hono das einzige Framework, das dir jede Option gibt. ElysiaJS ist Bun-only. NestJS ist praktisch Node-only.
Wie wir Services auf Cloud-Infrastruktur deployen, einschließlich Kubernetes, Lambda und Edge Functions, behandelt diese Seite.
Wann NestJS weiterhin die richtige Wahl ist
Trotz unserer Präferenz für Hono bei neuen Projekten ist NestJS die richtige Wahl, wenn:
- Du Vendure-Plugins baust. Vendure IST NestJS. Das Plugin-System, Services, Resolver und Guards nutzen alle NestJS-Patterns. Gegen das Framework zu arbeiten ist schlimmer als es zu nutzen.
- Dein Team Angular kennt. NestJS' Module/Provider/Controller-Pattern spiegelt Angular. Wenn dein Team von Angular kommt, ist die Lernkurve praktisch null.
- Du ein großes Middleware-Ökosystem brauchst. Passport Strategies, class-validator, Swagger Auto-Generierung, GraphQL Code-first. NestJS hat alles eingebaut oder gut integriert.
- Die Anwendung auf 100+ Dateien wachsen wird. NestJS Modules bieten Struktur, die skaliert. Ohne Konventionen (Hono, ElysiaJS) brauchen große Teams Disziplin, um Konsistenz zu halten.
- Du WebSocket-Support brauchst. NestJS hat eingebaute WebSocket-Gateways mit dem gleichen Decorator-Pattern. Honos WebSocket-Support ist manueller.
Häufige Stolperfallen
-
Hono wählen und dann NestJS nachbauen. Wenn du am Ende einen DI-Container, Decorator-basiertes Routing, ein Modul-System und ein Guard-Pattern zu Hono hinzufügst, hast du ein schlechteres NestJS gebaut. Nimm NestJS.
-
ElysiaJS für Produktion wählen, ohne Bun-Kompatibilität zu prüfen. Prüfe, ob alle deine Dependencies auf Bun laufen. Native Addons, bestimmte Datenbanktreiber und manche Crypto-Libraries funktionieren möglicherweise nicht.
-
Cold-Start-Zeiten bei Serverless ignorieren. NestJS auf Lambda ist für nutzerseitige APIs ohne Provisioned Concurrency unbenutzbar. Hono auf Lambda ist auch ohne das schnell genug.
-
TypeORM mit Hono nutzen. TypeORM ist für NestJS' DI-Patterns designed. Ohne DI wird das Verwalten von TypeORM-Connections und Repositories umständlich. Nutze Drizzle oder Prisma mit Hono.
-
Voreiliger Framework-Wechsel. Wenn deine NestJS-App funktioniert und dein Team produktiv ist, wechsle nicht zu Hono, nur um modern zu sein. Wechsle, wenn du einen konkreten Grund hast (Serverless-Deployment, Edge Functions, neuer eigenständiger Service).
-
Keine Validierungsschicht. Hono bringt keine Request-Validierung mit. Nutze Zod Middleware oder bau deine eigene. Eine API ohne Input-Validierung auszuliefern ist eine Sicherheitslücke.
Fazit
-
Hono ist das vielseitigste TypeScript-Backend-Framework. 14KB Core, läuft auf jeder Runtime, schnelle Cold Starts, keine Architektur-Vorgaben. Unser Standard für neue eigenständige APIs.
-
ElysiaJS liefert die beste Performance auf Bun. Eingebaute Validierung, großartige DX, End-to-End typsicher. Aber die Bun-Bindung schränkt ein, wohin du deployen kannst.
-
NestJS ist weiterhin die richtige Wahl für große Enterprise-Apps und Vendure. Modules, DI, Guards und ein riesiges Ökosystem. Die Lernkurve zahlt sich bei Skalierung aus.
-
Drizzle ist unser bevorzugtes ORM mit Hono. SQL-ähnliche Syntax, explizite Queries, leichtgewichtiges Bundle. Prisma für Teams, die auto-generierte Clients bevorzugen. TypeORM für NestJS/Vendure.
-
Das Deployment-Ziel bestimmt die Framework-Wahl. Serverless und Edge brauchen Hono. Container funktionieren mit allem. Bun-nativ braucht ElysiaJS.
-
Wechsle Frameworks nicht ohne Grund. Wenn NestJS funktioniert, nutze es weiter. Wechsle, wenn du Serverless, Edge oder einen neuen eigenständigen Service brauchst, bei dem der leichtgewichtige Ansatz tatsächlich besser ist.
Wir bauen TypeScript-Backends mit allen drei Frameworks als Teil unserer Webentwicklung und Custom Software Praxis. Wenn du Frameworks für ein neues Projekt evaluierst, sprich mit unserem Team oder fordere ein Angebot an.
Behandelte Themen
Verwandte Guides
Unternehmenshandbuch zu Agentischen KI-Systemen
Technischer Leitfaden zu agentischen KI-Systemen in Unternehmen. Erfahre mehr ueber Architektur, Faehigkeiten und Anwendungen autonomer KI-Agenten.
Guide lesenAgentic Commerce: Wie du KI-Agenten sicher einkaufen lässt
Wie du gesteuerten, KI-initiierten Handel designst. Policy Engines, HITL-Freigabe-Gates, HMAC-Quittungen, Idempotenz, Tenant-Scoping und das vollständige Agentic Checkout Protocol.
Guide lesenDie 9 Stellen, an denen dein KI-System Daten verliert (und wie du jede einzelne abdichtest)
Eine systematische Übersicht aller Stellen, an denen KI-Systeme Daten preisgeben. Prompts, Embeddings, Logs, Tool Calls, Agent Memory, Fehlermeldungen, Cache, Fine-Tuning-Daten und Agent Handoffs.
Guide lesenBereit, produktionsreife KI-Systeme zu bauen?
Unser Team ist spezialisiert auf produktionsreife KI-Systeme. Lass uns besprechen, wie wir deinem Unternehmen helfen können.
Gespräch starten