Live cursors with WebSockets

Server-Sent Events (see /sse) only push from the server to the browser. WebSockets talk both ways over one connection, which suits frequent small messages like cursor positions.

No plugin is needed: since Node 24.9, an upgrade request reaches the normal request handler, so the route /websocket/socket takes over the connection with reply.hijack() and speaks the WebSocket protocol in about 150 lines. Open this page in a second window and move your mouse in the room below.

Room

Connecting…

Move your pointer here · click to send a ripple

Waiting for the server…0 sent · 0 received

The room lives in the memory of one server process. Serverless platforms like Vercel don't keep connections open, so the WebSocket only works when the server runs on its own (e.g. with Docker).