Options
WebSocketOptions<In, Out> configures a connection. Pass it to createWebSocket(url, options) or useWebSocket(url, options).
Summary
Incoming data goes through parse (or json), then schema, before it reaches lastMessage and onMessage. Outgoing messages go through serialize (or json).
Connection
protocols
Sub-protocol(s) passed to the WebSocket constructor. With useWebSocket(url), connections are shared per URL and protocols.
binaryType
How binary messages are exposed: 'blob' (the browser default) or 'arraybuffer'.
WebSocket
The WebSocket implementation to use. In browsers it defaults to the global WebSocket. During a server render (when there is no window), the client never connects unless you pass an implementation here.
Use it for tests (a mock) or for Node (the ws package):
In development, pass a class from createChaosWebSocket to add latency, lost messages and dropped connections. See Chaos testing.
Messages
json
JSON.parse incoming messages and JSON.stringify outgoing ones.
Incoming data that isn't valid JSON is not delivered. It is reported to onError as a MessageError with the original data.
parse
A custom decoder for incoming event.data. It takes precedence over json. If it throws, the message is reported to onError as a MessageError (with the thrown error as cause) and not delivered.
serialize
A custom encoder for outgoing messages. It takes precedence over json. It must return something WebSocket.send accepts: a string, Blob, ArrayBuffer or typed array.
schema
Validate incoming messages, after parsing, with any Standard Schema library: zod 3.24+, valibot 1.0+, arktype 2.0+ and others. Invalid messages are reported to onError as a MessageError with issues and are not delivered. The In type is inferred from the schema.
Async schemas are supported. Messages are still delivered in the order they arrived.
Reliability
reconnect
Reconnect with exponential backoff after an unexpected close or a failed attempt. false disables reconnecting. An object tunes it:
The delay before attempt n is min(maxDelay, minDelay Ć factor^(nā1)), minus up to jitter of it at random. With the defaults, each delay is picked at random between 0 and 1 s, 2 s, 4 s, 8 s, ⦠up to 30 s.
When retryAfter returns a delay, the client waits that long plus the usual delay. A 1013 (Try Again Later) close that names no delay starts the backoff at maxDelay instead. See Overloaded servers.
While a retry is scheduled, the client also retries immediately when the browser fires online or the page becomes visible again, unless the server asked it to wait.
A shouldReconnect of your own replaces the default. Call the exported retryableClose from it to keep the default rule:
See Reconnecting and heartbeats.
heartbeat
Send a ping on an interval while open. Use it to keep connections alive through proxies that close idle connections, and, with timeout, to detect connections that died without a close event.
Any incoming message counts as a sign of life, not just pong.
A ping is also sent right away when the browser fires online or the page becomes visible again, unless one is already waiting for an answer. A connection that died while the laptop slept is then found within timeout, instead of after up to interval more.
queue
Buffer send() calls made while not connected, and send them in order when the socket opens.
To decide per message instead, pass SendOptions to send(): { volatile: true } drops one message, { key } keeps only the newest queued message per key, and { priority: true } queues a message ahead of the others, and { maxAge } drops one that waited too long.
Queued messages are sent right after open listeners run, so a handshake sent from onOpen goes out first. See First-message auth. The queue is cleared by close() and when the client gives up reconnecting.
Debugging
logger
Receives debug messages about connection attempts, retries, heartbeat timeouts and dropped messages.
Hook-only options
useWebSocket(url, options) also accepts onOpen, onMessage, onClose, onError and enabled. See Handlers.