API REST: Hands-on with Bun and Elysia.js 🦊
Welcome back fellows! Over the last two posts, we stripped away the bloated tools of the traditional Node.js era to streamline the realities of life behind the keyboard. Now, it is time to build. We are going to construct a modern REST API using the native power of Bun and a framework designed specifically for it: Elysia.js.
1. Why Elysia.js? (And Not Express?)
If you have written a backend before, you probably used Express. But running Express on Bun is like putting bicycle tires on a Ferrari. Elysia.js is an ergonomic web framework fine-tuned specifically for Bun.
- Raw Performance: It easily handles hundreds of thousands of requests per second by leveraging Bun's native HTTP server.
- Built-in Types: It infers types automatically without requiring you to write bloated manual TypeScript definitions.
- Chainable Syntax: The API design feels modern, clean, and intuitive.
2. The "Hello World" Setup
Starting a project with Elysia is practically instant. Open your terminal and run:
Bash
bun create elysia my-api
cd my-api
bun run dev
Let's look at how beautifully simple a basic server is in src/index.ts:
TypeScript
import { Elysia } from 'elysia';
const app = new Elysia()
.get('/', () => 'Hello from Elysia and Bun!')
.listen(3000);
console.log(`🦊 API running at ${app.server?.hostname}:${app.server?.port}`);
3. Type Safety Without the Headache
In a traditional setup, validating incoming JSON data requires installing heavy external libraries and writing manual middleware checks. Elysia has schema validation built-in (using TypeBox under the hood via the t object).
TypeScript
import { Elysia, t } from 'elysia';
const app = new Elysia()
.post('/users', ({ body }) => {
return { message: "User created", data: body };
}, {
body: t.Object({
name: t.String(),
email: t.String(),
age: t.Optional(t.Number())
})
})
.listen(3000);
The Magic: If someone sends aPOSTrequest missing the requirednamefield, Elysia automatically blocks it and returns a422 Unprocessable Entityerror before your function even runs!
4. What's Next?
Writing APIs with Bun and Elysia makes programming genuinely fun again. The tooling gets out of your way, the type inference is flawless, and the speed is unmatched. But an API on your local machine is only half the battle.
In Part 4, we are going to take this exact Elysia API, package it into a Docker container, and deploy it to our DigitalOcean droplet using Coolify!
Have you ever used built-in schema validation, or are you still manually checking if (!req.body.name) in your controllers?