interface

Server

interface Server<WebSocketData>

HTTP & HTTPS Server

To start the server, see serve

For performance, Bun pre-allocates most of the data for 2048 concurrent requests. That means starting a new server allocates about 500 KB of memory. Try to avoid starting and stopping the server often (unless it's a new instance of bun).

Powered by a fork of uWebSockets.

  • readonly development: boolean

    Whether the server is running in development mode.

    In development mode, Bun.serve() returns rendered error messages with stack traces instead of a generic 500 error. Don't use development mode in production: it risks leaking sensitive information.

  • readonly hostname: undefined | string

    The hostname the server is listening on. Does not include the port.

    This is undefined when the server is listening on a unix socket.

    "localhost"
  • readonly id: string

    An identifier of the server instance

    When bun is started with the --hot flag, this ID is used to hot reload the server without interrupting pending requests or websockets.

    When bun is not started with the --hot flag, this ID is unused.

  • readonly pendingRequests: number

    The number of in-flight requests

  • readonly pendingWebSockets: number

    The number of in-flight ServerWebSockets

  • readonly port: undefined | number

    The port the server is listening on.

    This is undefined when the server is listening on a unix socket.

    3000
  • readonly protocol: null | 'http' | 'https'

    The protocol the server is listening on.

    • "http" for normal servers
    • "https" when TLS is enabled
    • null for unix sockets or when unavailable
  • readonly url: URL
  • Close every connection that is not currently sending a request or waiting for a response, without stopping the server.

    In-flight requests and open WebSockets are untouched, and the server keeps accepting new connections.

    @returns

    The number of connections that were closed.

  • request: string | Request
    ): Response | Promise<Response>;

    Mock the fetch handler for a running server.

    This feature is not fully implemented: it doesn't normalize URLs consistently in all cases and it doesn't always call the error handler.

  • topic: string,
    data: string | ArrayBuffer | SharedArrayBuffer | Blob | ArrayBufferView<ArrayBufferLike>,
    compress?: boolean
    ): number;

    Send a message to all connected ServerWebSocket clients subscribed to a topic

    @param topic

    The topic to publish to

    @param data

    The data to send

    @param compress

    Should the data be compressed? Ignored if the client does not support compression.

    @returns

    0 if the message was dropped for any subscriber (or there were no subscribers), -1 if backpressure was applied for any subscriber, or the number of bytes sent.

    server.publish("chat", "Hello World");
  • ref(): void;

    Undo a call to Server.unref

    If the Server has already been stopped, this does nothing.

    If Server.ref is called multiple times, this does nothing.

  • reload<R extends string>(
    options: Options<WebSocketData, R>
    ): Server<WebSocketData>;

    Update the fetch and error handlers without restarting the server.

    // create the server
    const server = Bun.serve({
     fetch(request) {
       return new Response("Hello World v1")
     }
    });
    
    // Update the server to return a different response
    server.reload({
      fetch(request) {
        return new Response("Hello World v2")
      }
    });

    Passing other options such as port or hostname has no effect.

  • request: Request
    ): null | SocketAddress;

    Returns the client IP address and port of the given Request. If the request was closed or is a unix socket, returns null.

    export default {
     async fetch(request, server) {
       return new Response(server.requestIP(request));
     }
    }
  • closeActiveConnections?: boolean
    ): Promise<void>;

    Stop listening to prevent new connections from being accepted.

    By default, it does not cancel in-flight requests or websockets. Idle keep-alive connections are closed right away, and connections with a request in flight close as soon as their response completes. That means it may take some time before all network activity stops.

    The returned promise resolves once every connection is closed.

    @param closeActiveConnections

    Immediately terminate in-flight requests, websockets, and stop accepting new connections.

  • topic: string
    ): number;

    A count of connections subscribed to a given topic

    This loops through each topic internally to get the count.

    @param topic

    The websocket topic to count subscribers for

    @returns

    The number of subscribers

  • request: Request,
    seconds: number
    ): void;

    Reset the idle timeout of the given Request to the given number of seconds. 0 means no timeout.

    export default {
     async fetch(request, server) {
       server.timeout(request, 60);
       await Bun.sleep(30000);
       return new Response("30 seconds have passed");
     }
    }
  • unref(): void;

    Don't keep the process alive if this server is the only thing left. Active connections may continue to keep the process alive.

    By default, the server is ref'd.

    To prevent new connections from being accepted, use Server.stop

  • request: Request,
    ...options: [WebSocketData] extends [undefined] ? [options?: { data: undefined; headers: HeadersInit }] : [options: { data: WebSocketData; headers: HeadersInit }]
    ): boolean;

    Upgrade a Request to a ServerWebSocket

    @param request

    The Request to upgrade

    @param options

    Pass headers or attach data to the ServerWebSocket

    @returns

    true if the upgrade was successful and false if it failed

    import { serve } from "bun";
    const server: Bun.Server<{ user: string }> = serve({
      websocket: {
        open: (ws) => {
          console.log("Client connected");
        },
        message: (ws, message) => {
          console.log("Client sent message", message);
        },
        close: (ws) => {
          console.log("Client disconnected");
        },
      },
      fetch(req, server) {
        const url = new URL(req.url);
        if (url.pathname === "/chat") {
          const upgraded = server.upgrade(req, {
            data: {user: "John Doe"}
          });
          if (!upgraded) {
            return new Response("Upgrade failed", { status: 400 });
          }
        }
        return new Response("Hello World");
      },
    });

    What you pass to data is available on the ServerWebSocket.data property