BunHttpServer unstable
Bun implementation of the Effect HttpServer.
make creates a scoped HTTP server from Bun.serve, converting Bun
Request values into HttpServerRequest values and Effect
HttpServerResponse values back into Web Response values. The server
supports streaming bodies, multipart requests, file responses through
BunHttpPlatform, and WebSocket upgrades. Bun.serve cannot hand over the
connection for other protocols, so other upgrades fail. This module also
provides layers for the server alone, the Bun HTTP support services, the
combined server, configurable server options, and a test server with an
HTTP client.
Constructors
Creates a scoped Bun HttpServer from Bun.serve options, stopping the server on scope finalization with optional graceful shutdown settings.
Details
idleTimeout defaults to 0, disabling Bun's 10 second idle timeout, so
quiet response streams and slow uploads are bounded only by the Stream
and Effect timeouts in your handlers or middleware. An explicit value is
passed to Bun unchanged.
On shutdown the server waits up to gracefulShutdownTimeout (default 20
seconds) for in-flight requests, then interrupts the remaining request
fibers. disablePreemptiveShutdown: true skips the wait and interrupts
them immediately. Handlers run uninterruptibly unless wrapped in
Effect.interruptible or served by interruptible HttpRouter routes, so a
client disconnect does not stop them and shutdown waits for them to finish.
Gotchas
Without an idle timeout, Bun also keeps idle keep-alive connections and
clients that stopped reading a response open, and handler timeouts cannot
catch either. Directly exposed servers should set idleTimeout (seconds,
at most 255) or sit behind a proxy with its own idle timeout.
Signature
declare const make: <R extends string>(...args: [options: any]) => Effect<{ readonly address: SocketAddress; readonly serve: { <E, R>(effect: Effect<HttpServerResponse, E, R>): Effect<void, never, Scope | Exclude<R, HttpServerRequest>>; <E, R, App extends Effect<HttpServerResponse, any, any>>(effect: Effect<HttpServerResponse, E, R>, middleware: Applied<App, E, R>): Effect<void, never, Scope | Exclude<Services<App>, HttpServerRequest>>; };}, ServeError, Scope>Layers
Layer that provides a Bun HttpServer together with the Bun HTTP platform, ETag generator, and Bun services.
Details
idleTimeout defaults to 0 (disabled); see make.
Signature
declare function layer<R extends string>(options: any): Layer<HttpPlatform | Generator | BunServices | HttpServer, ServeError>layerConfig
unstableCreates the Bun HTTP server and support-services layer from configurable serve options.
Signature
declare function layerConfig<R extends string>(options: Config<any>): Layer<HttpPlatform | Generator | FileSystem | Path | HttpServer, ServeError | ConfigError>layerHttpServices
unstableLayer that provides Bun HTTP support services: HttpPlatform, weak ETag generation, and BunServices.
Signature
declare const layerHttpServices: Layer.Layer<HttpPlatform | Etag.Generator | BunServices.BunServices>layerServer
unstableLayer that provides only HttpServer by constructing a scoped Bun server from the supplied serve options.
Signature
declare const layerServer: <R extends string>(options: ServeOptions<R> & { readonly disablePreemptiveShutdown?: boolean; readonly gracefulShutdownTimeout?: Duration.Input; readonly websocket?: WebSocketOptions;}) => Layer.Layer<Server.HttpServer, Error.ServeError>Options
Bun serve options accepted by the HTTP server, extended with typed route definitions.
Signature
type ServeOptions<R extends string> = Bun.Serve.UnixServeOptions<WebSocketContext> | Bun.Serve.HostnamePortServeOptions<WebSocketContext> & { readonly routes?: Bun.Serve.Routes<WebSocketContext, R>;}WebSocket tuning options forwarded to Bun.serve's websocket handler.
Details
The lifecycle handlers (open, message, close, ...) are managed by the
server and cannot be overridden; everything else — such as
perMessageDeflate compression, payload limits, and idle timeouts — passes
through, e.g.
BunHttpServer.layer({ port: 3000, websocket: { perMessageDeflate: true } }).
The compressionThreshold option controls the minimum message size in bytes
that is compressed when per-message deflate is negotiated. It defaults to
1024, matching the default threshold of Node's ws server.
Signature
type WebSocketOptions = Omit<Bun.WebSocketHandler<WebSocketContext>, "open" | "message" | "close" | "drain" | "ping" | "pong" | "data" | "binaryType"> & { readonly compressionThreshold?: number;}