High-performance HTTP/WebSocket server with hot reloading, static file serving, TLS support, and comprehensive request/response handling optimized for modern web applications.
Create high-performance HTTP servers with comprehensive configuration options.
/**
* Start an HTTP server with the given options
* @param options - Server configuration options
* @returns Server instance
*/
function Bun.serve(options: Bun.ServeOptions): Server;
interface Bun.ServeOptions {
/** Request handler function */
fetch: (request: Request, server: Server) => Response | Promise<Response>;
/** Port number (default: random available port) */
port?: number;
/** Hostname to bind to (default: "localhost") */
hostname?: string;
/** Unix socket path (alternative to port/hostname) */
unix?: string;
/** WebSocket handler configuration */
websocket?: WebSocketHandler<any>;
/** TLS/SSL configuration */
tls?: TLSOptions;
/** Static file serving configuration */
static?: StaticOptions;
/** Server name for Server header */
serverName?: string;
/** Maximum request body size in bytes */
maxRequestBodySize?: number;
/** Development mode options */
development?: boolean;
/** Error handler for server errors */
error?: (error: Error) => Response | void;
/** Low-level socket options */
reusePort?: boolean;
/** Connection timeout in milliseconds */
timeout?: number;
}Usage Examples:
// Basic HTTP server
const server = Bun.serve({
port: 3000,
fetch(request) {
return new Response("Hello World!");
}
});
console.log(`Server listening on http://localhost:${server.port}`);
// JSON API server
const apiServer = Bun.serve({
port: 8080,
fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/api/users") {
return Response.json({ users: [{ id: 1, name: "Alice" }] });
}
return new Response("Not Found", { status: 404 });
}
});
// Server with error handling
const robustServer = Bun.serve({
port: 3000,
fetch(request) {
// Your request handler
return new Response("OK");
},
error(error) {
console.error("Server error:", error);
return new Response("Internal Server Error", { status: 500 });
}
});Integrated WebSocket support with automatic upgrade handling and message routing.
interface WebSocketHandler<T = any> {
/** Called when WebSocket connection opens */
open?(ws: ServerWebSocket<T>): void | Promise<void>;
/** Called when message is received */
message?(ws: ServerWebSocket<T>, message: string | Buffer): void | Promise<void>;
/** Called when WebSocket connection closes */
close?(ws: ServerWebSocket<T>, code: number, reason: string): void | Promise<void>;
/** Called when WebSocket error occurs */
error?(ws: ServerWebSocket<T>, error: Error): void | Promise<void>;
/** Called for WebSocket pings */
ping?(ws: ServerWebSocket<T>, data: Buffer): void | Promise<void>;
/** Called for WebSocket pongs */
pong?(ws: ServerWebSocket<T>, data: Buffer): void | Promise<void>;
/** Called when connection is being drained */
drain?(ws: ServerWebSocket<T>): void | Promise<void>;
/** Maximum message size in bytes */
maxPayloadLength?: number;
/** Idle timeout in seconds */
idleTimeout?: number;
/** Backpressure limit */
backpressureLimit?: number;
/** Whether to close on backpressure */
closeOnBackpressureLimit?: boolean;
}
interface ServerWebSocket<T = any> {
/** User data associated with this WebSocket */
data: T;
/** Ready state of the WebSocket */
readyState: number;
/** Remote address of the client */
remoteAddress: string;
/**
* Send a message to the WebSocket client
* @param message - Message to send (string or binary)
* @returns Number of bytes buffered
*/
send(message: string | ArrayBufferView | ArrayBuffer): number;
/**
* Send binary data to the WebSocket client
* @param data - Binary data to send
* @returns Number of bytes buffered
*/
sendBinary(data: ArrayBufferView | ArrayBuffer): number;
/**
* Send a ping frame
* @param data - Optional ping data
* @returns Number of bytes buffered
*/
ping(data?: ArrayBufferView | ArrayBuffer): number;
/**
* Send a pong frame
* @param data - Optional pong data
* @returns Number of bytes buffered
*/
pong(data?: ArrayBufferView | ArrayBuffer): number;
/**
* Close the WebSocket connection
* @param code - Close code
* @param reason - Close reason
*/
close(code?: number, reason?: string): void;
/**
* Terminate the connection immediately
*/
terminate(): void;
/**
* Subscribe to a topic for pub/sub messaging
* @param topic - Topic name to subscribe to
* @returns Success status
*/
subscribe(topic: string): boolean;
/**
* Unsubscribe from a topic
* @param topic - Topic name to unsubscribe from
* @returns Success status
*/
unsubscribe(topic: string): boolean;
/**
* Check if subscribed to a topic
* @param topic - Topic name to check
* @returns Whether subscribed
*/
isSubscribed(topic: string): boolean;
/**
* Publish message to all subscribers of a topic
* @param topic - Topic to publish to
* @param message - Message to publish
* @returns Number of subscribers that received the message
*/
publish(topic: string, message: string | ArrayBufferView | ArrayBuffer): number;
/**
* Get cork context for batching operations
* @param callback - Function to execute in cork context
*/
cork(callback: () => void): void;
}Usage Examples:
// WebSocket chat server
const chatServer = Bun.serve({
port: 3000,
fetch(req, server) {
// Upgrade HTTP requests to WebSocket
const success = server.upgrade(req, {
data: {
userId: req.headers.get("user-id"),
createdAt: Date.now()
}
});
if (success) return; // WebSocket upgrade successful
return new Response("HTTP not supported", { status: 400 });
},
websocket: {
open(ws) {
console.log("Client connected:", ws.data.userId);
ws.subscribe("chat-room");
},
message(ws, message) {
const data = JSON.parse(message.toString());
// Broadcast to all subscribers
ws.publish("chat-room", JSON.stringify({
userId: ws.data.userId,
message: data.message,
timestamp: Date.now()
}));
},
close(ws) {
console.log("Client disconnected:", ws.data.userId);
}
}
});
// Real-time data streaming
const streamServer = Bun.serve({
port: 8080,
fetch(req, server) {
if (req.headers.get("upgrade") === "websocket") {
server.upgrade(req);
return;
}
return new Response("WebSocket required", { status: 426 });
},
websocket: {
open(ws) {
// Send periodic updates
const interval = setInterval(() => {
ws.send(JSON.stringify({
timestamp: Date.now(),
data: Math.random()
}));
}, 1000);
ws.data.interval = interval;
},
close(ws) {
clearInterval(ws.data.interval);
}
}
});Server instance returned by Bun.serve with management methods.
interface Server {
/** Port the server is listening on */
readonly port: number;
/** Hostname the server is bound to */
readonly hostname: string;
/** Development mode status */
readonly development: boolean;
/** Whether server is using TLS */
readonly secure: boolean;
/**
* Upgrade an HTTP request to WebSocket
* @param request - HTTP request to upgrade
* @param options - WebSocket upgrade options
* @returns Whether upgrade was successful
*/
upgrade<T = any>(
request: Request,
options?: {
/** User data to associate with WebSocket */
data?: T;
/** WebSocket headers to include */
headers?: HeadersInit;
}
): boolean;
/**
* Publish message to all WebSocket subscribers
* @param topic - Topic to publish to
* @param message - Message to publish
* @returns Number of subscribers
*/
publish(
topic: string,
message: string | ArrayBufferView | ArrayBuffer
): number;
/**
* Stop the server
* @param force - Whether to force close connections
*/
stop(force?: boolean): void;
/**
* Reload the server (development mode)
*/
reload(options?: { port?: number }): void;
}Secure HTTPS server configuration with certificate management.
interface TLSOptions {
/** TLS certificate (PEM format) */
cert?: string | BunFile | ArrayBuffer;
/** TLS private key (PEM format) */
key?: string | BunFile | ArrayBuffer;
/** Certificate authority chain */
ca?: string | BunFile | ArrayBuffer;
/** Passphrase for encrypted private key */
passphrase?: string;
/** DH parameters for perfect forward secrecy */
dhParamsFile?: string;
/** Whether to request client certificates */
requestCert?: boolean;
/** Whether to reject unauthorized client certificates */
rejectUnauthorized?: boolean;
/** Server name for SNI */
serverName?: string;
/** Allowed cipher suites */
ciphers?: string;
/** Minimum TLS version */
secureProtocol?: string;
}Usage Examples:
// HTTPS server with Let's Encrypt certificates
const httpsServer = Bun.serve({
port: 443,
tls: {
cert: Bun.file("/etc/letsencrypt/live/example.com/fullchain.pem"),
key: Bun.file("/etc/letsencrypt/live/example.com/privkey.pem")
},
fetch(request) {
return new Response("Secure Hello World!");
}
});
// Self-signed certificate for development
const devServer = Bun.serve({
port: 8443,
tls: {
cert: `-----BEGIN CERTIFICATE-----
MIICljCCAX4CCQDAOxKQn2CzJA==
-----END CERTIFICATE-----`,
key: `-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQ==
-----END PRIVATE KEY-----`
},
fetch(request) {
return new Response("Development HTTPS");
}
});Built-in static file serving with caching, compression, and security features.
interface StaticOptions {
/** Root directory for static files */
root?: string;
/** Default files to serve for directories */
index?: string[];
/** Whether to follow symlinks */
followSymlinks?: boolean;
/** Custom headers for static responses */
headers?: Record<string, string>;
/** MIME type mappings */
mimeTypes?: Record<string, string>;
/** Enable gzip compression */
compress?: boolean;
/** Cache control settings */
maxAge?: number;
/** ETag generation */
etag?: boolean;
/** Last-Modified header */
lastModified?: boolean;
}Usage Examples:
// Static file server with SPA support
const staticServer = Bun.serve({
port: 3000,
static: {
root: "./public",
index: ["index.html"],
headers: {
"Cache-Control": "public, max-age=3600"
}
},
fetch(request) {
// SPA fallback - serve index.html for non-API routes
const url = new URL(request.url);
if (!url.pathname.startsWith("/api/")) {
return Bun.file("./public/index.html");
}
return new Response("API endpoint", { status: 404 });
}
});/** HTTP methods supported by Bun server */
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
/** WebSocket ready states */
const enum WebSocketReadyState {
CONNECTING = 0,
OPEN = 1,
CLOSING = 2,
CLOSED = 3
}
/** Server error types */
interface ServerError extends Error {
code?: string;
address?: string;
port?: number;
syscall?: string;
}
/** Request context passed to fetch handler */
interface RequestContext {
request: Request;
server: Server;
url: URL;
}