Last Updated: 3/7/2026
WebSocket Helper
WebSocket Helper is a helper for server-side WebSockets in Hono applications. Currently Cloudflare Workers / Pages, Deno, and Bun adapters are available.
Import
Cloudflare Workers:
import { Hono } from 'hono'
import { upgradeWebSocket } from 'hono/cloudflare-workers'Deno:
import { Hono } from 'hono'
import { upgradeWebSocket } from 'hono/deno'Bun:
import { Hono } from 'hono'
import { upgradeWebSocket, websocket } from 'hono/bun'
export default {
fetch: app.fetch,
websocket,
}If you use Node.js, you can use @hono/node-ws .
upgradeWebSocket()
upgradeWebSocket() returns a handler for handling WebSocket.
const app = new Hono()
app.get(
'/ws',
upgradeWebSocket((c) => {
return {
onMessage(event, ws) {
console.log(`Message from client: ${event.data}`)
ws.send('Hello from server!')
},
onClose: () => {
console.log('Connection closed')
},
}
})
)Available events:
onOpen- Currently, Cloudflare Workers does not support it.onMessageonCloseonError
If you use middleware that modifies headers (e.g., applying CORS) on a route that uses WebSocket Helper, you may encounter an error saying you can’t modify immutable headers. This is because upgradeWebSocket() also changes headers internally.
RPC-mode
Handlers defined with WebSocket Helper support RPC mode.
// server.ts
const wsApp = app.get(
'/ws',
upgradeWebSocket((c) => {
//...
})
)
export type WebSocketApp = typeof wsApp
// client.ts
const client = hc<WebSocketApp>('http://localhost:8787')
const socket = client.ws.$ws() // A WebSocket object for a clientExamples
Server and Client
// server.ts
import { Hono } from 'hono'
import { upgradeWebSocket } from 'hono/cloudflare-workers'
const app = new Hono().get(
'/ws',
upgradeWebSocket(() => {
return {
onMessage: (event) => {
console.log(event.data)
},
}
})
)
export default app// client.ts
import { hc } from 'hono/client'
import type app from './server'
const client = hc<typeof app>('http://localhost:8787')
const ws = client.ws.$ws(0)
ws.addEventListener('open', () => {
setInterval(() => {
ws.send(new Date().toString())
}, 1000)
})