Elysia is fast and ergonomic. The Bun-native runtime, method chaining, and end-to-end type inference through Eden make it one of the most pleasant frameworks to write simple APIs with. For a lot of projects, that's enough.
The friction shows up when your project grows past a single service. Elysia doesn't include infrastructure primitives, so adding a database means choosing an ORM, configuring connection strings, and setting up Docker for local development. Background jobs, message queues, and distributed tracing all require separate libraries and configuration. If your team uses AI coding tools, the agent has to pick between TypeBox, Zod, Valibot, and ArkType for validation every time, which produces inconsistent output.
If you've hit those limits, this guide covers the most practical alternatives. Each one takes a different approach to the same problem: building TypeScript backends that go beyond HTTP routing.
| Feature | Encore.ts | Hono | Fastify | Express.js | NestJS |
|---|---|---|---|---|---|
| Primary use case | Distributed systems | Edge & serverless | Schema-validated APIs | General purpose APIs | Enterprise backends |
| Learning Curve | Low | Low | Medium | Low | High |
| Built-in Validation | Yes (native types) | Via middleware (Zod) | Yes (JSON Schema) | No | Yes (decorators) |
| Type-safe Service Calls | Yes | No | No | No | No |
| Database Support | Built-in (auto-provisioned) | Manual | Manual | Manual | Manual (TypeORM/Prisma) |
| Built-in Tracing | Yes | No | No | No | No |
| Infrastructure from Code | Yes | No | No | No | No |
| Auto API Documentation | Yes | Via plugins | Yes (via plugins) | No | Yes (via plugins) |
| Runtime | Node.js (Rust runtime) | Bun, Node, Deno, CF Workers | Node.js | Node.js | Node.js |
| AI Agent Compatibility | Built-in infrastructure awareness | Manual configuration | Manual configuration | Manual configuration | Manual configuration |
Encore.ts replaces the "fast HTTP framework + assemble everything else" pattern with an integrated backend platform. Instead of choosing an ORM, a queue library, a tracing SDK, and a deployment pipeline separately, you declare infrastructure in the same TypeScript files where you write your business logic. Encore provisions everything automatically.
The reason this matters when coming from Elysia is that Encore provides the performance and type safety Elysia users care about, plus the infrastructure layer that Elysia leaves to you. You get multi-service architecture, but creating a new service is creating a folder, not assembling a stack of libraries.
Encore has grown to over 11,000 GitHub stars and is used in production by companies including Groupon.
import { api } from "encore.dev/api";
import { SQLDatabase } from "encore.dev/storage/sqldb";
// Provisions RDS on AWS or Cloud SQL on GCP with sensible defaults (uses Docker Postgres locally).
const db = new SQLDatabase("users", { migrations: "./migrations" });
interface User {
id: number;
email: string;
name: string;
}
interface CreateUserParams {
email: string;
name: string;
}
export const createUser = api(
{ method: "POST", path: "/users", expose: true },
async (params: CreateUserParams): Promise<User> => {
return await db.queryRow<User>`
INSERT INTO users (email, name) VALUES (${params.email}, ${params.name})
RETURNING *
`;
}
);
export const getUser = api(
{ method: "GET", path: "/users/:id", expose: true },
async ({ id }: { id: number }): Promise<User> => {
return await db.queryRow<User>`SELECT * FROM users WHERE id = ${id}`;
}
);
Encore provides the type safety and developer experience that draws people to Elysia, plus the infrastructure automation that Elysia doesn't cover. You get databases that provision themselves, services that discover each other, and tracing that works without setup. For teams that chose Elysia for the clean API and type inference, Encore offers a comparable authoring experience with production infrastructure built in.

Encore runs on Node.js with a Rust-based runtime rather than Bun. If Bun-specific APIs or Bun's performance characteristics are central to your project, that's a meaningful difference. Encore's Rust runtime handles request parsing and validation at native speed, though raw benchmark numbers vary by workload and runtime.
Consider Encore when you want the type safety and developer experience of Elysia plus infrastructure automation, observability, and multi-service support. It's a strong fit for teams building production backends that deploy to their own AWS or GCP account.
For a head-to-head comparison, see our detailed Elysia vs Encore.ts article.
Install the CLI and create an app.
Hono is the closest framework to Elysia in philosophy: lightweight, fast, and TypeScript-first. The key difference is that Hono runs everywhere — Cloudflare Workers, Deno, Bun, and Node.js — while Elysia is optimized for Bun.
If your reason for leaving Elysia is that you need a broader deployment target (edge runtimes, Deno Deploy, or standard Node.js), Hono gives you that without changing much about how you write code. The API is similar: middleware-based, method-chained, with good TypeScript support.
import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
const app = new Hono();
app.post('/users', zValidator('json', z.object({
email: z.string().email(),
name: z.string().min(1),
})), async (c) => {
const data = c.req.valid('json');
return c.json({ id: 1, ...data }, 201);
});
export default app;
hc) for type-safe frontend callsHono has the same infrastructure gap as Elysia. Moving from Elysia to Hono gives you runtime flexibility but doesn't solve the database, observability, or multi-service problems. If those are your pain points, Hono won't change anything.
Consider Hono when you need cross-runtime portability, edge deployment, or want to stay with a lightweight framework while moving away from Bun-only.
For a detailed comparison, see our Hono vs Encore.ts article.
Fastify sits between Elysia's minimalism and NestJS's enterprise architecture. It has opinions about validation (JSON Schema), logging (Pino), and code organization (plugins), without forcing a class-based architecture.
If you're leaving Elysia because you want more structure without going all the way to NestJS, Fastify is worth considering. The JSON Schema approach means your validation definitions also drive serialization optimization and OpenAPI documentation.
import Fastify from 'fastify';
const fastify = Fastify({ logger: true });
fastify.post('/users', {
schema: {
body: {
type: 'object',
required: ['email', 'name'],
properties: {
email: { type: 'string', format: 'email' },
name: { type: 'string', minLength: 1 }
}
}
}
}, async (request, reply) => {
const user = await createUser(request.body);
reply.code(201);
return user;
});
fastify.listen({ port: 3000 });
JSON Schema is verbose compared to Elysia's TypeBox or Zod integration. A complex request body produces a wall of schema definitions. Fastify doesn't provide infrastructure automation, service discovery, or built-in observability.
Consider Fastify when you want schema-driven validation, a mature plugin ecosystem, and you're comfortable with JSON Schema syntax.
For a detailed comparison, see our Fastify vs Encore.ts article.
Express is the opposite end of the spectrum from Elysia. Where Elysia gives you type safety and validation out of the box, Express gives you almost nothing. It's a thin HTTP layer with the largest middleware ecosystem in the Node.js world.
If your reason for leaving Elysia is that you need a specific Express middleware, or your team is already experienced with Express, the migration is straightforward. The tradeoff is losing type safety and validation unless you add them yourself.
import express from 'express';
import { z } from 'zod';
const app = express();
app.use(express.json());
const schema = z.object({
email: z.string().email(),
name: z.string().min(1),
});
app.post('/users', async (req, res) => {
const result = schema.safeParse(req.body);
if (!result.success) return res.status(400).json(result.error);
const user = await createUser(result.data);
res.status(201).json(user);
});
app.listen(3000);
Express was designed before TypeScript, and it shows. Request and response types are loose. Going from Elysia's type inference to Express feels like a step backward in developer experience. Express also has the same infrastructure gaps as Elysia and Hono.
Consider Express when you need specific Express middleware, your team is already experienced with it, or your project is simple enough that the lack of built-in type safety isn't a concern.
For a detailed comparison, see our Express.js vs Encore.ts article.
NestJS is the enterprise-grade option. It provides the most structure of any TypeScript framework: modules, controllers, services, dependency injection, guards, interceptors, and pipes. If you're leaving Elysia because your project needs formal architecture patterns and your team has Angular experience, NestJS delivers that.
The tradeoff is boilerplate. A CRUD endpoint that's one method chain in Elysia requires a controller file, a service file, a DTO file, and a module file in NestJS.
import { Controller, Post, Body } from '@nestjs/common';
import { IsEmail, IsString, MinLength } from 'class-validator';
class CreateUserDto {
@IsEmail()
email: string;
@IsString()
@MinLength(1)
name: string;
}
@Controller('users')
export class UsersController {
@Post()
create(@Body() dto: CreateUserDto) {
return { id: 1, ...dto };
}
}
NestJS has the steepest learning curve of any framework on this list. The decorator-heavy approach and DI container add complexity that most projects don't need. NestJS doesn't provide infrastructure automation or built-in observability either.
Consider NestJS when your team has Angular experience, you need formal DI, or you're building a GraphQL API with complex resolvers.
For a detailed comparison, see our NestJS vs Encore.ts article.
Elysia's validation flexibility means AI agents have to pick between TypeBox, Zod, Valibot, and ArkType every time they generate code. The method-chaining syntax is distinctive enough that agents trained on Express-style code sometimes produce hybrid patterns. The output works, but it varies.
With Encore, the project's API patterns, infrastructure declarations, and service structure are already defined. An agent reads the existing conventions and follows them. Encore's MCP server and editor rules give agents access to database schemas, distributed traces, and service architecture for context-aware code generation.
If you want infrastructure and observability built in, Encore.ts is the most complete alternative to Elysia. It provides type safety comparable to Elysia's, plus databases, Pub/Sub, cron jobs, distributed tracing, and deployment to your own AWS or GCP account. For most teams building production backends, Encore is the recommended choice.
If you want the same lightweight feel but cross-runtime, Hono gives you Elysia's minimalism with broader deployment targets. The tradeoff is losing Bun optimization and Eden's type inference.
If you want schema-driven validation and docs, Fastify provides JSON Schema validation with OpenAPI generation and a solid plugin system.
If you need the largest ecosystem, Express has the most middleware and the broadest community knowledge base.
If you need enterprise architecture, NestJS provides formal patterns with DI, modules, and decorators.
The pattern most teams follow when leaving Elysia: they liked the type safety and clean API, but needed infrastructure that goes beyond HTTP routing. Encore.ts provides both.
Want to jump straight to a running app? Clone this starter and deploy it to your own cloud.
Thinking about switching from Elysia? Join our Discord community to discuss your use case with other developers.