DEV Community

Alex Spinov
Alex Spinov

Posted on

Elysia Has a Free API: The Fastest Bun Framework With End-to-End Type Safety

Elysia is a TypeScript web framework optimized for Bun. It's the fastest framework in the Bun ecosystem, with built-in validation, end-to-end type safety like tRPC, and Eden — a fully typed client.

Why Elysia?

  • Fastest — 140K+ req/s on Bun, faster than Express by 18x
  • End-to-end types — Eden client with full autocompletion
  • Built-in validation — schema validation via TypeBox
  • Plugin system — Swagger, JWT, CORS, GraphQL, WebSocket
  • Ergonomic — Express-like DX with modern features

Quick Start

bun create elysia my-app
cd my-app
bun run dev
Enter fullscreen mode Exit fullscreen mode

Basic API

import { Elysia, t } from 'elysia';

const app = new Elysia()
  .get('/', () => 'Hello Elysia!')

  .get('/users', () => [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
  ])

  .get('/users/:id', ({ params: { id } }) => {
    return { id, name: 'Alice' };
  })

  .post('/users', ({ body }) => {
    return { id: 3, ...body };
  }, {
    body: t.Object({
      name: t.String({ minLength: 1 }),
      email: t.String({ format: 'email' }),
    }),
  })

  .listen(3000);

console.log(`Running at ${app.server?.url}`);
Enter fullscreen mode Exit fullscreen mode

Eden (Type-Safe Client)

// server.ts
const app = new Elysia()
  .get('/users', () => [{ id: 1, name: 'Alice' }])
  .post('/users', ({ body }) => ({ id: 2, ...body }), {
    body: t.Object({ name: t.String(), email: t.String() }),
  });

export type App = typeof app;

// client.ts
import { treaty } from '@elysiajs/eden';
import type { App } from './server';

const client = treaty<App>('localhost:3000');

// Fully typed! IDE autocompletes everything
const { data: users } = await client.users.get();
const { data: newUser } = await client.users.post({
  name: 'Charlie',
  email: 'charlie@example.com',
});
Enter fullscreen mode Exit fullscreen mode

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())           // /swagger
  .use(cors())
  .use(jwt({ secret: 'my-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?.replace('Bearer ', ''));
    if (!payload) throw new Error('Unauthorized');
    return { userId: payload.userId };
  })

  .listen(3000);
Enter fullscreen mode Exit fullscreen mode

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', { user: ws.id, message });
    },
    close(ws) {
      ws.unsubscribe('chat-room');
    },
  })
  .listen(3000);
Enter fullscreen mode Exit fullscreen mode

Performance

Framework Req/s (Bun)
Elysia 140K
Hono 130K
Fastify 65K
Express 8K

Resources


Building fast APIs? Check my Apify actors or email spinov001@gmail.com.

Top comments (0)