Elysia is the fastest Bun web framework with end-to-end type safety. Its API is elegant, fully typed, and blazingly fast — handling 2.5M req/sec on a single thread.
Basic API
import { Elysia, t } from "elysia"
const app = new Elysia()
.get("/", () => "Hello Elysia")
.get("/users", async () => {
return db.user.findMany()
})
.get("/users/:id", async ({ params: { id } }) => {
return db.user.findUnique({ where: { id } })
})
.post("/users", async ({ body }) => {
return db.user.create({ data: body })
}, {
body: t.Object({
name: t.String({ minLength: 2 }),
email: t.String({ format: "email" })
})
})
.listen(3000)
console.log(`Running at ${app.server?.hostname}:${app.server?.port}`)
Type-Safe Validation with TypeBox
import { Elysia, t } from "elysia"
const app = new Elysia()
.post("/products", ({ body }) => {
// body is fully typed: { name: string, price: number, tags: string[] }
return createProduct(body)
}, {
body: t.Object({
name: t.String(),
price: t.Number({ minimum: 0 }),
tags: t.Array(t.String())
}),
response: t.Object({
id: t.String(),
name: t.String(),
price: t.Number(),
createdAt: t.String()
})
})
Plugin System
const authPlugin = new Elysia({ name: "auth" })
.derive(({ headers }) => {
const token = headers.authorization?.replace("Bearer ", "")
return { userId: token ? verifyToken(token) : null }
})
.macro(({ onBeforeHandle }) => ({
isAuth(enabled: boolean) {
if (enabled) {
onBeforeHandle(({ userId, error }) => {
if (!userId) return error(401, "Unauthorized")
})
}
}
}))
const app = new Elysia()
.use(authPlugin)
.get("/public", () => "Anyone can see this")
.get("/private", ({ userId }) => `Hello user ${userId}`, {
isAuth: true
})
Groups & Guards
const app = new Elysia()
.group("/api/v1", (app) =>
app
.get("/health", () => ({ status: "ok" }))
.guard({
headers: t.Object({
authorization: t.String()
})
}, (app) =>
app
.get("/users", () => db.user.findMany())
.get("/posts", () => db.post.findMany())
.delete("/users/:id", ({ params }) => db.user.delete({ where: { id: params.id } }))
)
)
WebSocket
const app = new Elysia()
.ws("/chat", {
body: t.Object({
message: t.String()
}),
open(ws) {
ws.subscribe("chat-room")
},
message(ws, { message }) {
ws.publish("chat-room", { from: ws.id, message })
},
close(ws) {
ws.unsubscribe("chat-room")
}
})
Eden Treaty — End-to-End Type Safety
// Client-side — fully typed from server definition!
import { treaty } from "@elysiajs/eden"
import type { App } from "./server"
const api = treaty<App>("localhost:3000")
// Fully typed — autocomplete works!
const { data } = await api.users.get()
const { data: user } = await api.users({ id: "123" }).get()
const { data: created } = await api.users.post({
name: "John",
email: "john@example.com"
})
Key Takeaways
- 2.5M req/sec — fastest Bun framework
- End-to-end type safety with Eden Treaty
- TypeBox validation with automatic typing
- Plugin system with derive and macros
- Guards for grouped middleware
- WebSocket with typed messages
Explore Elysia docs for the complete API.
Building web scrapers or data pipelines? Check out my Apify actors for ready-made solutions, or email spinov001@gmail.com for custom development.
Top comments (0)