Build High-Performance REST APIs with Bun in 2026
JavaScript runtimes have evolved rapidly. While Node.js has been the undisputed king for over a decade, 2025 and 2026 have seen a massive shift toward Bun for high-performance backend development. As of February 2026, Bun is solidifying its place as a serious alternative to Node.js, especially for API development.
In this guide, we will explore how to build a robust REST API using Bun—specifically leveraging its native Bun.serve HTTP server and the new built-in Bun.sql database client.
Why Bun in 2026?
Bun is a modern JavaScript runtime designed for speed. It is written in Zig and uses the JavaScriptCore engine (unlike Node.js which uses V8).
- Blazingly Fast Startup: Bun starts significantly faster than Node.js.
- Native APIs:
Bun.servereplaces Express-like patterns with a built-in, high-performance server. - Built-in Database Support: No need for heavy ORM drivers; Bun has native SQLite and SQL support.
- Zero Dependencies: You can build entire APIs without installing a single
npmpackage.
Prerequisites
Ensure you have Bun installed:
curl -fsSL https://bun.sh/install | bash
1. Setting Up the Project
Create a new directory and initialize it:
mkdir bun-api-tutorial
cd bun-api-tutorial
bun init
2. Building the Server with Bun.serve
Create a file named server.ts. We will build a simple Todo API.
The Code
import { BunSQLite } from "bun:sqlite";
// 1. Initialize Database
const db = new BunSQLite("todos.db");
// Create table if not exists
db.query(`
CREATE TABLE IF NOT EXISTS todos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task TEXT NOT NULL,
completed INTEGER DEFAULT 0
)
`).run();
// 2. Configure the Server
const server = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
const method = req.method;
// Simple Router Logic
if (url.pathname === "/todos" && method === "GET") {
// GET /todos
const todos = db.query("SELECT * FROM todos").all();
return new Response(JSON.stringify(todos), {
headers: { "Content-Type": "application/json" }
});
}
if (url.pathname === "/todos" && method === "POST") {
// POST /todos
const { task } = await req.json();
if (!task) {
return new Response(JSON.stringify({ error: "Task is required" }), { status: 400 });
}
const info = db.query("INSERT INTO todos (task) VALUES (?)").run(task);
const newTodo = db.query("SELECT * FROM todos WHERE id = ?").get(info.lastInsertRowid);
return new Response(JSON.stringify(newTodo), {
headers: { "Content-Type": "application/json" },
status: 201
});
}
if (url.pathname.startsWith("/todos/") && method === "PUT") {
// PUT /todos/:id
const id = url.pathname.split("/")[2];
const { completed } = await req.json();
db.query("UPDATE todos SET completed = ? WHERE id = ?").run(completed ? 1 : 0, id);
const updated = db.query("SELECT * FROM todos WHERE id = ?").get(id);
return new Response(JSON.stringify(updated), {
headers: { "Content-Type": "application/json" }
});
}
if (url.pathname.startsWith("/todos/") && method === "DELETE") {
// DELETE /todos/:id
const id = url.pathname.split("/")[2];
db.query("DELETE FROM todos WHERE id = ?").run(id);
return new Response(JSON.stringify({ message: "Deleted" }), { status: 204 });
}
return new Response("Not Found", { status: 404 });
}
});
console.log(`Server running at http://localhost:${server.port}`);
Key Features Used
-
BunSQLite: A built-in interface to SQLite. It requires no external drivers.query(...).run(...)is for actions, and.all()/.get()are for reads. -
Bun.serve: This replaces the need for Express or Fastify for simple use cases. It handles requests natively using the Web API standard (RequestandResponseobjects).
3. Testing the API
Run the server:
bun run server.ts
You can test it using curl or Postman:
Create a Todo:
curl -X POST http://localhost:3000/todos \
-H "Content-Type: application/json" \
-d '{"task": "Learn Bun in 2026"}'
List Todos:
curl http://localhost:3000/todos
Performance Considerations
In benchmarks, Bun handles simple JSON APIs significantly faster than Node.js (often 2-3x faster in I/O operations) and with much lower memory usage.
Conclusion
Bun is no longer just an experiment; it is a production-ready runtime that simplifies the backend stack. By removing the dependency on external HTTP frameworks and database drivers, Bun allows you to build high-performance APIs with minimal code.
Try converting your next Node.js microservice to Bun and see the speed difference yourself!
Top comments (0)