Skip to content

Add first class WebSocket support to @hono/node-server #307

@BlankParticle

Description

@BlankParticle

Currently for WebSocket support in node we need to install @honojs/node-ws middleware along with @honojs/node-server, then create some helper functions with createNodeWebSocket and pass them around.
So a basic echo websocket server looks like this,

import { serve } from "@hono/node-server";
import { createNodeWebSocket } from "@hono/node-ws";
import { Hono } from "hono";

const app = new Hono();

const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });

app.get(
  "/ws",
  upgradeWebSocket((c) => ({
    onMessage(event, ws) {
      ws.send(event.data);
    },
  })),
);

const server = serve(app);
injectWebSocket(server);

this is awkward because you need to create an app, then use that to create helper and then chain on the app again to setup helpers, and you also need to remember to call injectWebSocket. I personally had experiences where I didn't create the helpers properly, or had multiple routers but did use the correct one or forgot to inject and debug why my ws server is not working.

on the other side, hono/bun has first class support for WebSockets because bun makes it really easy to do so. You import upgradeWebSocket from hono/bun anywhere, and just need to pass in websocket from hono/bun to Bun.serve

thus, I wanted to make WebSockets a first class supported feature in @hono/node-server, I have made a branch on my fork exploring this and is currently using it.

// Using my fork
import { serve, upgradeWebSocket } from '@blankparticle/hono-node-server'
import { Hono } from 'hono'

const app = new Hono()

app.get(
  '/ws',
  upgradeWebSocket(() => ({
    onMessage(event, ws) {
      ws.send(event.data)
    },
  }))
)

serve({
  fetch: app.fetch,
  websocket: true, // opt into using websockets
})

npm: https://www.npmjs.com/package/@blankparticle/hono-node-server
github: main...BlankParticle:node-server:blank/fork

this makes the experience same as hono/bun, adds ws as a dependency to @hono/node-server, I ran the benchmarks and I see a ±2% difference when WebSockets is enabled, which can be taken as measurement error on my macbook.

If this is something we can add to @hono/node-server, I will be happy to make proper PRs with my changes, so we can add the first class WebSocket support, and deprecate @hono/node-ws and update the docs

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions