Connection

thunderclapJS manages one WebSocket per client. It reconnects on its own with exponential backoff, and resubscribes every channel when it does.

States

client.ts
thunderclap.on("state", ({ previous, current }) => console.log(previous, "→", current));
thunderclap.on("error", ({ code, message }) => console.error(code, message));
StateMeans
initializedCreated with autoConnect: false, not connected yet
connectingOpening the connection
connectedReady: subscriptions are active
reconnectingLost the connection; a reconnect is scheduled
closedClosed by disconnect()
failedRefused for good, e.g. an unknown key or a suspended app: no automatic reconnect

Call connect() to connect after autoConnect: false or disconnect(), or to retry now instead of waiting for the backoff. See error codes for what makes a connection fail.

Excluding the sender

When a user's action triggers a broadcast, they usually shouldn't receive their own echo. Send thunderclap.socketId to your backend with the request, and pass it as exclude:

client.ts
await fetch("/api/messages", {
  method: "POST",
  body: JSON.stringify({ text, socketId: thunderclap.socketId }),
});
server.ts
await thunderclap.publish({ channel: "room-42", data, exclude: req.body.socketId });

Custom domains and local development

The SDKs connect to https://realtime.thunderclap.dev unless you pass url. Set it only for a custom domain, for example from THUNDERCLAP_URL.