DEV Community

Alex Spinov
Alex Spinov

Posted on

ElysiaJS Has a Free Bun-Native Framework That Handles 2.5M Requests Per Second

Express handles ~15K req/s. Fastify does ~77K. ElysiaJS on Bun does 2.5 million — and the developer experience is better than both.

Why ElysiaJS

ElysiaJS is built specifically for Bun runtime. It uses:

  • Bun's native HTTP server (fastest in JS ecosystem)
  • Static code analysis for route compilation
  • End-to-end type safety with TypeBox
  • Plugin-based architecture

Hello World

import { Elysia } from "elysia";

const app = new Elysia()
  .get("/", () => "Hello World")
  .get("/users/:id", ({ params: { id } }) => ({ userId: id }))
  .listen(3000);

console.log(`Running at http://localhost:${app.server?.port}`);
Enter fullscreen mode Exit fullscreen mode
bun run index.ts
Enter fullscreen mode Exit fullscreen mode

Type-Safe Everything

import { Elysia, t } from "elysia";

const app = new Elysia()
  .post("/users", ({ body }) => {
    // body is fully typed: { name: string, email: string, age: number }
    return { id: crypto.randomUUID(), ...body };
  }, {
    body: t.Object({
      name: t.String({ minLength: 1 }),
      email: t.String({ format: "email" }),
      age: t.Number({ minimum: 0 }),
    }),
    response: t.Object({
      id: t.String(),
      name: t.String(),
      email: t.String(),
      age: t.Number(),
    }),
  })
  .get("/users", ({ query }) => {
    // query.page is typed as number
    return { page: query.page, users: [] };
  }, {
    query: t.Object({
      page: t.Number({ default: 1 }),
      limit: t.Number({ default: 10 }),
    }),
  });
Enter fullscreen mode Exit fullscreen mode

Validation + TypeScript types generated from a single schema definition.

Plugins

import { Elysia } from "elysia";
import { swagger } from "@elysiajs/swagger";
import { jwt } from "@elysiajs/jwt";
import { cors } from "@elysiajs/cors";

const app = new Elysia()
  .use(swagger())      // Auto-generated Swagger docs at /swagger
  .use(cors())         // CORS handling
  .use(jwt({ secret: process.env.JWT_SECRET! }))
  .post("/login", async ({ jwt, body }) => {
    const token = await jwt.sign({ userId: body.userId });
    return { token };
  })
  .get("/protected", async ({ jwt, headers }) => {
    const payload = await jwt.verify(headers.authorization?.split(" ")[1]);
    if (!payload) throw new Error("Unauthorized");
    return { user: payload };
  });
Enter fullscreen mode Exit fullscreen mode

Eden (End-to-End Type Safety)

// Client side — like tRPC but for REST
import { edenTreaty } from "@elysiajs/eden";
import type { App } from "./server";

const api = edenTreaty<App>("http://localhost:3000");

// Fully typed — TypeScript knows the response shape
const { data } = await api.users.post({
  name: "Alice",
  email: "alice@test.com",
  age: 30,
});
console.log(data.id); // Typed as string
Enter fullscreen mode Exit fullscreen mode

Groups and Guards

const app = new Elysia()
  .group("/api/v1", (app) =>
    app
      .get("/users", getUsers)
      .post("/users", createUser)
  )
  .guard({ headers: t.Object({ authorization: t.String() }) }, (app) =>
    app
      .get("/admin/stats", getStats)
      .delete("/admin/users/:id", deleteUser)
  );
Enter fullscreen mode Exit fullscreen mode

Benchmark

Framework Runtime Requests/sec
Express Node.js ~15,000
Fastify Node.js ~77,000
Hono Bun ~150,000
ElysiaJS Bun ~2,500,000

Need high-performance APIs or data solutions? I build web tools and scraping infrastructure. Email spinov001@gmail.com or check my Apify tools.

Top comments (0)