WebSocket

Docs

WebSockets keep one bidirectional connection open so the browser and server can both send messages. This demo connects, sends a message, receives echoes and heartbeats, and reconnects after connection loss. Use WebSockets when clients must send live input without opening a new HTTP request. For one-way server updates, see SSE Stream.

Disconnected

Heartbeat ping every 15s; reconnects after drops, not page refresh

Connect to open the socket and start sending messages
Reference Code
import { Hono } from "hono";
import { createBunWebSocket } from "hono/bun";
import type { ServerWebSocket } from "bun";

const { upgradeWebSocket, websocket } =
  createBunWebSocket<ServerWebSocket>();

const app = new Hono();

app.get("/api/websocket", upgradeWebSocket(() => {
  let heartbeat: ReturnType<typeof setInterval> | undefined;

  return {
    onOpen(_event, ws) {
      ws.send(JSON.stringify({
        type: "system",
        message: "Connected. Send a message to echo it back.",
      }));

      heartbeat = setInterval(() => {
        ws.send(JSON.stringify({ type: "heartbeat", message: "ping" }));
      }, 15000);
    },
    onMessage(event, ws) {
      ws.send(JSON.stringify({
        type: "echo",
        message: String(event.data),
        timestamp: new Date().toISOString(),
      }));
    },
    onClose() {
      clearInterval(heartbeat);
    },
  };
}));

export default {
  fetch: app.fetch,
  websocket,
};
Ready
Output will appear here...