use-websocket
Open a WebSocket with raw payloads.
| Package | @vizejs/composable/use-websocket |
| Own the source | vize lib pull composable:use-websocket |
| Runtime exports | useWebSocket |
| Gzip budget | 4864 B |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/composable
Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.
import { useWebSocket } from "@vizejs/composable/use-websocket";
Try it
Connect a chat to a WebSocket
Open a WebSocket on demand, send messages and react to the connection state.
What to observe: Connect opens the socket; Say hello sends a message and shows the echo. Say hello is enabled only while the socket is open.
The docs have no server, so host supplies an echo socket; drop it in your app. Use heartbeat to detect dead connections and bufferWhileConnecting to queue early messages.
Compare the initial and interacted states


Copy the example
Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.
<script setup lang="ts">
import { useWebSocket } from "@vizejs/composable/use-websocket";
// The docs have no server, so this class echoes messages back. In your app, drop `host`
// and use your WebSocket server's URL.
class EchoServer extends EventTarget {
constructor(_url: string) {
super();
queueMicrotask(() => this.dispatchEvent(new Event("open")));
}
send(data: unknown) {
queueMicrotask(() =>
this.dispatchEvent(new MessageEvent("message", { data: `Echo: ${String(data)}` })),
);
}
close() {
queueMicrotask(() => this.dispatchEvent(new CloseEvent("close", { code: 1000 })));
}
}
const { status, data, open, close, send } = useWebSocket("wss://chat.example.com", {
host: EchoServer,
immediate: false,
autoReconnect: false,
});
</script>
<template>
<div class="composable-example">
<p>Connect a chat to a WebSocket server and react to its connection state.</p>
<div class="example-actions">
<button type="button" :disabled="status !== 'closed'" @click="() => open()">Connect</button>
<button type="button" :disabled="status !== 'open'" @click="() => send('Hello!')">
Say hello
</button>
<button type="button" :disabled="status === 'closed'" @click="() => close()">
Disconnect
</button>
</div>
<output aria-live="polite">Status: {{ status }}{{ data ? ` · ${data}` : "" }}</output>
</div>
</template>
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useWebSocket |
networking | experimental | deterministic-fallback | caller-managed | caller, reactive-scope | web, server, worker, native, desktop, terminal | Blob, globalThis, window |
calculateRetryDelay, tryOnScopeDispose |
API
useWebSocket
Open a WebSocket with raw payloads.
function useWebSocket( url: MaybeRefOrGetter<string | URL | null | undefined>, options?: UseWebSocketOptions<WebSocketRawData, WebSocketSendData>, ): WebSocketControls<WebSocketRawData, WebSocketSendData>
useWebSocket
Open a WebSocket with typed messages. parse is required unless raw payloads fit Incoming; serialize is required unless Outgoing is already sendable.
function useWebSocket<Incoming = WebSocketRawData, Outgoing = WebSocketSendData>( url: MaybeRefOrGetter<string | URL | null | undefined>, options: UseWebSocketOptions<Incoming, Outgoing> & WebSocketCodecRequirements<Incoming, Outgoing>, ): WebSocketControls<Incoming, Outgoing>
useWebSocket
Reactive WebSocket with typed messages, auto-reconnect, and heartbeat. Unexpected closes reconnect with exponential backoff when autoReconnect is enabled; close() is always final until open() is called again. Messages sent while connecting are queued. The connection and all timers are released when the owning reactive scope stops; outside a scope the caller owns close(). Server rendering never connects: automatic connection requires a browser or an explicit host, and status stays "closed".
function useWebSocket( url: MaybeRefOrGetter<string | URL | null | undefined>, options: UseWebSocketOptions<unknown, unknown> = {}, ): WebSocketControls<unknown, unknown>
const chat = useWebSocket<ChatEvent, ChatCommand>("wss://example.test/chat", {
parse: (raw) => parseChatEvent(String(raw)),
serialize: (command) => JSON.stringify(command),
autoReconnect: { retries: 5 },
heartbeat: true,
});
chat.send({ type: "join", room: "general" });
Types
WebSocketLike
Minimal WebSocket instance used by useWebSocket.
| Member | Type | Description |
|---|---|---|
send |
(data: WebSocketSendData) => void |
Transmit data over the open connection. |
close |
(code?: number, reason?: string) => void |
Start the closing handshake. |
addEventListener |
(type: "open" | "message" | "error" | "close", listener: EventListener) => void |
Subscribe to open, message, error, or close. |
removeEventListener |
(type: "open" | "message" | "error" | "close", listener: EventListener) => void |
Remove a listener registered with addEventListener. |
WebSocketReconnectOptions
Options for automatic reconnection.
| Member | Type | Description |
|---|---|---|
initialDelayMs? |
number |
Delay before the first retry, in milliseconds. |
multiplier? |
number |
Exponential multiplier applied for each subsequent retry. Values may be fractional but must be finite and at least one. The calculated delay is rounded up so a retry never starts earlier than the requested backoff. |
maximumDelayMs? |
number |
Inclusive ceiling for the calculated delay, in milliseconds. The ceiling may be lower than RetryDelayOptions.initialDelayMs; in that case it also caps the first retry. |
jitterRatio? |
number |
Fraction of the capped delay eligible for downward jitter. 0 is deterministic exponential backoff, 0.5 samples from the upper half of the range, and 1 applies full jitter from zero through the capped delay. Jitter never exceeds the unjittered delay. |
random? |
() => number |
Entropy source returning a number in the half-open interval [0, 1). It is called exactly once when the selected jitter range contains more than one integer millisecond, and is otherwise not read. |
retries? |
number |
Maximum consecutive reconnection attempts. |
onFailed? |
() => void |
Called once reconnection gives up. |
WebSocketHeartbeatOptions
Options for the keep-alive heartbeat.
| Member | Type | Description |
|---|---|---|
message? |
WebSocketSendData |
Raw ping payload. |
responseMessage? |
string |
Incoming payload treated as a pong and not exposed as data. |
intervalMs? |
number |
Delay between pings in milliseconds. |
pongTimeoutMs? |
number |
Close (and possibly reconnect) when no message arrives this long after a ping. |
UseWebSocketOptions
Options for useWebSocket. Callbacks that consume message types use method syntax so options typed for concrete messages remain assignable to the implementation signature.
| Member | Type | Description |
|---|---|---|
protocols? |
string | string[] |
Sub-protocols requested from the server. |
host? |
MaybeRef<WebSocketConstructorLike | null | undefined> |
WebSocket constructor (a plain value or ref; never a getter, because a constructor is itself a function). Supplying one also enables automatic connection outside a browser. |
immediate? |
boolean |
Connect as soon as a URL is available (browser or explicit host only). |
autoReconnect? |
boolean | WebSocketReconnectOptions |
Reconnect after unexpected closes with exponential backoff. |
heartbeat? |
boolean | WebSocketHeartbeatOptions |
Send periodic pings and drop connections whose peer stops answering. |
parse? |
(raw: WebSocketRawData) => Incoming |
Decode incoming payloads. |
serialize? |
(message: Outgoing) => WebSocketSendData |
Encode outgoing messages. |
validate? |
(message: Incoming) => boolean |
Reject parsed messages that fail this check ("invalid" failure). |
bufferWhileConnecting? |
boolean |
Queue messages sent while connecting and flush them on open. |
scheduler? |
TimeoutScheduler |
Timer host for reconnection and heartbeat. |
onMessage? |
(message: Incoming, event: Event) => void |
Observe every accepted incoming message. |
onError? |
(failure: WebSocketFailure) => void |
Observe failures. |
WebSocketControls
Reactive state and controls returned by useWebSocket.
| Member | Type | Description |
|---|---|---|
status |
Readonly<Ref<WebSocketStatus>> |
Connection status. |
data |
Readonly<ShallowRef<Incoming | undefined>> |
Latest accepted incoming message. |
error |
Readonly<ShallowRef<WebSocketFailure | undefined>> |
Latest failure, cleared when a connection opens. |
reconnectAttempts |
Readonly<Ref<number>> |
Consecutive reconnection attempts since the last successful open. |
socket |
Readonly<ShallowRef<WebSocketLike | undefined>> |
Current underlying socket, if any. |
send |
(message: Outgoing) => boolean |
Send a message, or queue it while connecting. |
open |
() => void |
Open (or reopen) the connection and re-enable reconnection. |
close |
(code?: number, reason?: string) => void |
Close the connection and disable automatic reconnection. |