namespace
Serve
namespace Serve
interface BaseServeOptions<WebSocketData>
- id?: null | string
Uniquely identify a server instance with an ID
When bun is started with the
--hotflag:Bun uses this string to hot reload the server without interrupting pending requests or websockets. If not provided, a value is generated. To disable hot reloading, set this value to
null.When bun is not started with the
--hotflag:This string has no effect.
- tls?: TLSOptions | TLSOptions[]
Set options for using TLS with this server
const server = Bun.serve({ fetch: request => new Response("Welcome to Bun!"), tls: { cert: Bun.file("cert.pem"), key: Bun.file("key.pem"), ca: [Bun.file("ca1.pem"), Bun.file("ca2.pem")], }, });
interface DirectoryRouteOptions
Serve a directory tree at a URL prefix.
The route path must end in
/*. The part of the request URL after the prefix is percent-decoded once and opened relative todir. Non-canonical paths (containing.,.., empty segments,%2F, or a%XXsequence encoding a character that may appear literally in a path segment) are rejected with404so the served path is always the path the router matched. On Linux the open usesopenat2(RESOLVE_IN_ROOT), so symlinks that would escapedirare clamped by the kernel. Routing is case-sensitive but filesystems on macOS and Windows are not by default: do not place access-controlled content insidedirand rely on an overlapping route to gate it.Responses carry
Content-Type(from the file extension),Last-Modified, a weakETag, and support single-rangeRangerequests. A request that resolves to a directory without a trailing/is redirected (301) to the trailing-slash URL; with the trailing slash,index.htmlfrom that directory is served. Missing files return404.Bun.serve({ routes: { "/static/*": { dir: "./public" }, }, });- statCache?: boolean
Cache formatted
Last-Modifiedstrings per path so repeated requests for an unchanged file skip the date formatter. Uses ~20 KB per route.
interface HostnamePortServeOptions<WebSocketData>
- hostname?: string & {} | '0.0.0.0' | '127.0.0.1' | 'localhost'
The hostname the server listens on
"127.0.0.1" // Only listen locally - http1?: boolean
Listen for HTTP/1.1 over TCP. Set to
falsetogether withhttp3: trueto serve HTTP/3 only. - id?: null | string
Uniquely identify a server instance with an ID
When bun is started with the
--hotflag:Bun uses this string to hot reload the server without interrupting pending requests or websockets. If not provided, a value is generated. To disable hot reloading, set this value to
null.When bun is not started with the
--hotflag:This string has no effect.
- idleTimeout?: number
Sets the number of seconds to wait before timing out a connection due to inactivity.
- reusePort?: boolean
Whether the
SO_REUSEPORTflag should be set.This allows multiple processes to bind to the same port, which is useful for load balancing.
- tls?: TLSOptions | TLSOptions[]
Set options for using TLS with this server
const server = Bun.serve({ fetch: request => new Response("Welcome to Bun!"), tls: { cert: Bun.file("cert.pem"), key: Bun.file("key.pem"), ca: [Bun.file("ca1.pem"), Bun.file("ca2.pem")], }, });
interface UnixServeOptions<WebSocketData>
- id?: null | string
Uniquely identify a server instance with an ID
When bun is started with the
--hotflag:Bun uses this string to hot reload the server without interrupting pending requests or websockets. If not provided, a value is generated. To disable hot reloading, set this value to
null.When bun is not started with the
--hotflag:This string has no effect.
- tls?: TLSOptions | TLSOptions[]
Set options for using TLS with this server
const server = Bun.serve({ fetch: request => new Response("Welcome to Bun!"), tls: { cert: Bun.file("cert.pem"), key: Bun.file("key.pem"), ca: [Bun.file("ca1.pem"), Bun.file("ca2.pem")], }, }); - unix?: string
If set, the HTTP server listens on a unix socket instead of a port. (Cannot be used with hostname+port)
- type BaseRouteValue =| Response| false| BunFile
- type Development =| boolean| { chromeDevToolsAutomaticWorkspaceFolders: boolean; console: boolean; hmr: boolean }
Development configuration for Bun.serve
- type ExtractRouteParams<T> = string extends T ? Record<string, string> : T extends `${string}:${infer Param}/${infer Rest}` ? { [K in Param]: string } & ExtractRouteParams<Rest> : T extends `${string}:${infer Param}` ? { [K in Param]: string } : T extends `${string}*` ? {} : {}
- type FetchOrRoutes<WebSocketData, R extends string> =
- type FetchOrRoutesWithWebSocket<WebSocketData, R extends string> = { websocket: WebSocketHandler<WebSocketData> } & { routes: RoutesWithUpgrade<WebSocketData, R>; fetch(this: Server<WebSocketData>, req: Request, server: Server<WebSocketData>): MaybePromise<undefined | void | Response> } | { routes: RoutesWithUpgrade<WebSocketData, R>; fetch(this: Server<WebSocketData>, req: Request, server: Server<WebSocketData>): MaybePromise<undefined | void | Response> }
- type Handler<Req extends Request, S, Res> = (request: Req, server: S) => MaybePromise<Res>
- type HTTPMethod =| 'GET'| 'POST'| 'PUT'| 'DELETE'| 'PATCH'| 'HEAD'| 'OPTIONS'
- type Options<WebSocketData, R extends string = string> = Bun.__internal.XOR<HostnamePortServeOptions<WebSocketData>, UnixServeOptions<WebSocketData>> & Bun.__internal.XOR<FetchOrRoutes<WebSocketData, R>, FetchOrRoutesWithWebSocket<WebSocketData, R>>
Options for serve, with support for
routesand a safer requirement forfetchexport default { fetch: req => Response.json(req.url), websocket: { message(ws) { ws.data.name; // string }, }, } satisfies Bun.Serve.Options<{ name: string }>; - type Routes<WebSocketData, R extends string> = { [K in R]: BaseRouteValue | Handler<BunRequest<Path>, Server<WebSocketData>, Response> | Partial<Record<HTTPMethod, Handler<BunRequest<Path>, Server<WebSocketData>, Response> | Response>> }
- type RoutesWithUpgrade<WebSocketData, R extends string> = { [K in R]: BaseRouteValue | Handler<BunRequest<Path>, Server<WebSocketData>, Response | undefined | void> | Partial<Record<HTTPMethod, Handler<BunRequest<Path>, Server<WebSocketData>, Response | undefined | void> | Response>> }