DEV Community

Alex Spinov
Alex Spinov

Posted on

Bun Has a Free HTTP Server API: Build Blazing-Fast APIs Without Express

Why Bun's HTTP Server?

Bun includes a built-in HTTP server that's 5-10x faster than Node.js + Express. No npm install needed — just Bun.serve() and you have a production-ready server.

Quick Start

Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Hello World!");
  },
});
console.log("Server running on http://localhost:3000");
Enter fullscreen mode Exit fullscreen mode

Run: bun run server.ts

Routing

Bun.serve({
  port: 3000,
  async fetch(req) {
    const url = new URL(req.url);

    if (url.pathname === "/api/users" && req.method === "GET") {
      const users = await db.query("SELECT * FROM users");
      return Response.json(users);
    }

    if (url.pathname === "/api/users" && req.method === "POST") {
      const body = await req.json();
      const user = await db.query("INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *", [body.name, body.email]);
      return Response.json(user, { status: 201 });
    }

    if (url.pathname.startsWith("/api/users/") && req.method === "GET") {
      const id = url.pathname.split("/")[3];
      const user = await db.query("SELECT * FROM users WHERE id = $1", [id]);
      return user ? Response.json(user) : new Response("Not found", { status: 404 });
    }

    return new Response("Not Found", { status: 404 });
  },
});
Enter fullscreen mode Exit fullscreen mode

File Serving

Bun.serve({
  port: 3000,
  async fetch(req) {
    const url = new URL(req.url);
    const filePath = `./public${url.pathname}`;
    const file = Bun.file(filePath);

    if (await file.exists()) {
      return new Response(file);
    }
    return new Response("Not found", { status: 404 });
  },
});
Enter fullscreen mode Exit fullscreen mode

Bun.file() streams files efficiently — zero-copy for large files.

WebSocket Server

Bun.serve({
  port: 3000,
  fetch(req, server) {
    if (server.upgrade(req)) return;
    return new Response("Upgrade failed", { status: 500 });
  },
  websocket: {
    open(ws) { console.log("Client connected"); },
    message(ws, message) {
      ws.send(`Echo: ${message}`);
      // Broadcast to all
      ws.publish("chat", message);
    },
    close(ws) { console.log("Client disconnected"); },
  },
});
Enter fullscreen mode Exit fullscreen mode

Built-in WebSocket with pub/sub — no ws or socket.io needed.

SQLite (Built-In)

import { Database } from "bun:sqlite";

const db = new Database("myapp.sqlite");
db.run("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)");

Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);
    if (url.pathname === "/users") {
      const users = db.query("SELECT * FROM users").all();
      return Response.json(users);
    }
    return new Response("OK");
  },
});
Enter fullscreen mode Exit fullscreen mode

SQLite is built into Bun — no npm packages.

Benchmark

Framework Requests/sec (hello world)
Bun.serve() ~150,000
Node.js http ~50,000
Express ~15,000
Fastify ~45,000
Deno.serve() ~80,000

Error Handling

Bun.serve({
  port: 3000,
  fetch(req) {
    // Your handler
  },
  error(error) {
    return new Response(`Error: ${error.message}`, { status: 500 });
  },
});
Enter fullscreen mode Exit fullscreen mode

Need high-performance APIs or server optimization?

📧 spinov001@gmail.com
🔧 My tools on Apify Store

Bun, Deno, or Node — which runtime do you pick?

Top comments (0)