# Bun

The Bun adapter wraps the native `Bun.serve` API for REST API deployments. You get fast startup, a smaller memory footprint, and first-class TLS and Unix-socket support without extra middleware.

**Diagram: Bun adapter stack**

- **Your DaloyJS App** - routes · hooks · handlers
- **Bun adapter** - serve(app) wraps Bun.serve - [idleTimeout, tls, unix]
- **Bun runtime** - native Bun.serve, fast startup

serve() hands your app to the native Bun.serve so routing stays owned by DaloyJS. Bun's built-in routes option is intentionally unused to keep the same REST API portable across runtimes.

## When to choose Bun

- You want startup measured in milliseconds and lower per-request overhead than Node.
- You ship a single self-contained binary or a small container.
- You're fine with Bun 1.2+ (matches the adapter's expectations).

## Scaffold

The `bun-basic` template ships a Bun-native server with `bun test` and Hey API codegen.

```bash
pnpm create daloy@latest my-api --template bun-basic
cd my-api
pnpm dev    # daloy dev --runtime bun (hot-reload)
```

## Install

```bash
bun add @daloyjs/core
```

## Minimal server

```ts
// src/server.ts
import { serve } from "@daloyjs/core/bun";
import { app } from "./app.ts";

const handle = serve(app, {
  port: 3000,
  hostname: "0.0.0.0",
  idleTimeout: 30,          // seconds; Bun default is 10
  development: false,       // disables Bun's dev error pages in prod
  // unix: "/tmp/daloy.sock",
  // tls: { cert, key },    // HTTPS
});

console.log("listening on " + handle.url);
```

## Graceful shutdown

The adapter listens for `SIGTERM` / `SIGINT` by default (matching the Node and Deno adapters), drains `app.shutdown()` hooks, and stops the Bun server. This means a rolling deploy under Kubernetes or systemd never hard-kills in-flight requests. Tune or opt out per deployment:

```ts
const handle = serve(app, {
  shutdownTimeoutMs: 15_000, // drain window passed to app.shutdown() (default 10s)
  handleSignals: false,      // manage signals yourself; call handle.stop() manually
});

// handle.stop() is idempotent: drains hooks first, then force-stops Bun.
await handle.stop();
```

## Hot reload in dev

```bash
bun --hot src/server.ts
```

## Dockerfile

```docker
FROM oven/bun:1.2-slim AS build
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
RUN bun build --target=bun src/server.ts --outdir dist

FROM oven/bun:1.2-distroless
WORKDIR /app
COPY --from=build /app/dist ./dist
EXPOSE 3000
CMD ["dist/server.js"]
```

## Gotchas

- `idleTimeout` is in **seconds**, capped at 255. Pass `0` to disable.
- Some npm packages with native bindings still need Node, test before committing to Bun in production.
- Bun's built-in `routes` option is not used by the adapter; routing is owned by DaloyJS so the same REST API stays portable across runtimes.

## See also

- [Adapters overview](/docs/adapters)
- [Node.js adapter](/docs/adapters/node)

---

Source: https://daloyjs.dev/docs/adapters/bun