**Ephemeral HTTP mock servers for integration tests, built for Bun.**
npm install bun-mock-builderEphemeral HTTP mock servers for integration tests, built for Bun.
bun-mock-builder lets you spin up real HTTP servers during tests, with a controlled lifecycle and a fluent builder API โ no request interception, no heavy setup.
---
bun-mock-builder is a tiny library for building ephemeral HTTP mock servers in Bun. You define routes with a fluent builder API and run them inside your tests.
When testing integrations, you often need to mock external APIs.
But:
- the real backend is not ready
- third-party APIs are unstable or rate-limited
- intercepting fetch does not behave like production
- CI environments need predictable, isolated infrastructure
This is a real HTTP server, not request interception.
It uses Bun.serve and runs alongside your tests, giving you real network behavior with a controlled lifecycle.
---
``ts
import { test, expect, beforeAll, afterAll } from "bun:test";
import { mock, type RunningMockServer } from "bun-mock-builder";
let server: RunningMockServer;
beforeAll(async () => {
server = await mock()
.post("/users", async (ctx) => {
const body = await ctx.json<{ name?: string }>();
return ctx.status(201).json({ id: 1, name: body.name ?? "" });
})
.listen(0); // random port
});
afterAll(async () => {
await server.close();
});
test("creates user", async () => {
const res = await fetch(${server.url}/users, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ name: "Joao" }),
});
const json = await res.json();
expect(res.status).toBe(201);
expect(json.name).toBe("Joao");
});
`
---
- ๐งช Real HTTP server (no fetch interception)Bun.serve
- โก Bun-first, built on afterAll
- ๐ Ephemeral lifecycle (start in a test, stop in )
- ๐ง Builder pattern inspired by Elysia
- ๐งฉ Designed for integration testing and CI
- ๐งฑ Lightweight middleware + groups for shared setup
---
bun-mock-builder includes an optional typed HTTP client for tests.
It provides:
- typed paths
- typed params
- typed request bodies
- typed responses
`ts
import { createClient } from "bun-mock-builder";
interface Person {
id: string;
name: string;
}
interface Api {
"/users/:id": {
GET: { response: Person };
};
"/users": {
POST: {
body: { name: string };
response: Person;
};
};
}
const api = createClient
baseUrl: "https://example.com",
});
const user = await api.get("/users/:id", { params: { id: "123" } });
const created = await api.post("/users", { body: { name: "Joao" } });
`
---
- Ephemeral mock servers with a controlled lifecycle
- Fluent builder API: .get, .post, .put, .delete.use
- Middleware and grouping: , .grouplisten(port?)
- with fixed or random ports (0){ url, port, buildUrl(), close() }
- Server handle with
- ctx.queryctx.headers
- ctx.method
- ctx.path
- await ctx.json()
-
- ctx.jsonctx.text
- ctx.status
-
- 404 for missing routes
- 500 for handler errors
- Runtime status code validation (100โ599)
- MockServerBuilder โ builder used to define routes and start the serverRunningMockServer
- โ returned by .listen(), exposes url, port, and close()MockContext
- โ context passed to route handlersHandler
- โ function that receives MockContext and returns ResponseMiddleware
- โ (ctx, next) => Response | Promise
- ctx.json(data, status?, headers?)ctx.text(text, status?, headers?)
- ctx.status(code).json(data, headers?)
- ctx.status(code).text(text, headers?)
- ctx.status(code).empty(headers?)
- โ useful for 204 or 304 responsesctx.res(body?, init?)
- โ create a new mutable Responsectx.clone(res)
- โ clone a Response (useful in middlewares)
Middlewares are executed in the order they are registered. Groups inherit middlewares
from the parent builder.
`ts`
mock()
.use(async (ctx, next) => {
const res = await next();
const cloned = ctx.clone(res);
cloned.headers.set("x-mock", "true");
return cloned;
})
.group("/v1", (group) => {
group.get("/health", () => new Response("ok"));
});
For safer URL composition:
`ts`
const server = await mock().get("/users", () => new Response("ok")).listen(0);
await fetch(server.buildUrl("/users"));
---
- This is not a web framework
- This is not request interception
- This is not a replacement for production servers
bun-mock-builder` is focused on test infrastructure.
Built with Bun v1.3.4.