DEV Community

1xApi
1xApi

Posted on • Originally published at 1xapi.com

Build High-Performance REST APIs with Bun in 2026

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.serve replaces 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 npm package.

Prerequisites

Ensure you have Bun installed:

curl -fsSL https://bun.sh/install | bash
Enter fullscreen mode Exit fullscreen mode

1. Setting Up the Project

Create a new directory and initialize it:

mkdir bun-api-tutorial
cd bun-api-tutorial
bun init
Enter fullscreen mode Exit fullscreen mode

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}`);
Enter fullscreen mode Exit fullscreen mode

Key Features Used

  1. BunSQLite: A built-in interface to SQLite. It requires no external drivers. query(...).run(...) is for actions, and .all()/.get() are for reads.
  2. Bun.serve: This replaces the need for Express or Fastify for simple use cases. It handles requests natively using the Web API standard (Request and Response objects).

3. Testing the API

Run the server:

bun run server.ts
Enter fullscreen mode Exit fullscreen mode

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"}'
Enter fullscreen mode Exit fullscreen mode

List Todos:

curl http://localhost:3000/todos
Enter fullscreen mode Exit fullscreen mode

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)