JSPM

react-websocket-kit

1.0.3
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 16
    • Score
      100M100P100Q75698F
    • License MIT

    A high-performance React WebSocket library with channel subscriptions, event-driven architecture, connection keep-alive, auto-reconnect, and UMD/CDN support.

    Package Exports

    • react-websocket-kit

    Readme

    react-websocket-kit

    A high-performance React WebSocket client with channel/event pub-sub routing, heartbeat keep-alive, auto-reconnect with exponential backoff, and UMD/CDN support.


    Features

    • 🔌 useWebSocket hook — Component-level WebSocket with full lifecycle control
    • 📡 Channel & Event Pub/Sub — Subscribe to structured { channel, event, payload } messages
    • 🔁 Auto-Reconnect — Exponential backoff with configurable attempts and max delay
    • 💓 Heartbeat Keep-Alive — Detect dead connections and self-heal automatically
    • 🌐 Shared Connections<WebSocketProvider> shares a single socket across your component tree
    • 📦 Dual Build — ESM (import) and UMD (<script> tag) outputs
    • 🏷️ Full TypeScript — Ships .d.ts declarations for every export

    Installation

    npm / yarn / pnpm

    npm install react-websocket-kit
    # or
    yarn add react-websocket-kit
    # or
    pnpm add react-websocket-kit

    CDN (Script Tag)

    <!-- React 18 (peer dependency) -->
    <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    
    <!-- React WebSocket Kit -->
    <script src="https://unpkg.com/react-websocket-kit/dist/index.umd.cjs"></script>
    
    <script>
      // All exports available on the global namespace:
      const { useWebSocket, WebSocketProvider, useWebSocketEvent, ReadyState } = ReactWebSocketKit;
    </script>

    Quick Start

    1. Basic Hook Usage

    Use useWebSocket for a single component-scoped connection:

    import { useWebSocket, ReadyState } from 'react-websocket-kit';
    
    function LiveStatus() {
      const { readyState, sendRaw, lastMessage } = useWebSocket('ws://localhost:8080');
    
      return (
        <div>
          <p>Status: {readyState === ReadyState.OPEN ? '🟢 Connected' : '🔴 Offline'}</p>
          <button onClick={() => sendRaw('Hello Server!')}>Send</button>
          <p>Last message: {lastMessage?.data}</p>
        </div>
      );
    }

    2. Channel & Event Pub/Sub

    All structured messages follow a standard envelope:

    {
      "channel": "chat:lobby",
      "event": "new_message",
      "payload": { "sender": "Alice", "text": "Hello!" }
    }

    Emitting events

    const { emit } = useWebSocket('ws://localhost:8080');
    
    // Sends: {"channel":"chat:lobby","event":"new_message","payload":{"text":"Hi"}}
    emit('chat:lobby', 'new_message', { text: 'Hi' });

    Subscribing to events (imperative)

    const { subscribe } = useWebSocket('ws://localhost:8080');
    
    useEffect(() => {
      const unsubscribe = subscribe('chat:lobby', 'new_message', (payload) => {
        console.log(payload.text);
      });
      return unsubscribe;
    }, []);

    Subscribing to events (declarative hook)

    import { useWebSocketEvent } from 'react-websocket-kit';
    
    function ChatMessages() {
      const [messages, setMessages] = useState([]);
    
      // Auto-subscribes on mount, auto-unsubscribes on unmount
      useWebSocketEvent('chat:lobby', 'new_message', (payload) => {
        setMessages((prev) => [...prev, payload]);
      });
    
      return (
        <ul>
          {messages.map((m, i) => (
            <li key={i}>{m.sender}: {m.text}</li>
          ))}
        </ul>
      );
    }

    3. Shared Connection via Provider

    Wrap your app in <WebSocketProvider> to share a single socket across all child components:

    import { WebSocketProvider, useSharedWebSocket, useWebSocketEvent } from 'react-websocket-kit';
    
    function App() {
      return (
        <WebSocketProvider url="ws://localhost:8080" options={{ heartbeat: true }}>
          <Dashboard />
          <Notifications />
        </WebSocketProvider>
      );
    }
    
    function Dashboard() {
      const { emit, readyState } = useSharedWebSocket();
      // emit(), sendRaw(), subscribe() all available here
    }
    
    function Notifications() {
      useWebSocketEvent('alerts', 'new_alert', (payload) => {
        alert(payload.message);
      });
    }

    API Reference

    useWebSocket(url, options?)

    The core hook. Returns a connection instance.

    Parameter Type Description
    url string | () => string | Promise<string> WebSocket server URL or async resolver
    options WebSocketOptions Configuration (see below)

    WebSocketOptions

    Option Type Default Description
    manual boolean false If true, won't connect on mount — call connect() manually
    reconnect boolean | ReconnectOptions true Auto-reconnect config (see below)
    heartbeat boolean | HeartbeatOptions false Keep-alive config (see below)
    queryParams Record<string, string | number | boolean> Appended to the connection URL
    protocols string | string[] WebSocket sub-protocols
    onOpen (event: Event) => void Fires on connection open
    onClose (event: CloseEvent) => void Fires on connection close
    onMessage (event: MessageEvent) => void Fires on every raw incoming message
    onError (event: Event) => void Fires on WebSocket error

    ReconnectOptions

    Option Type Default Description
    attempts number Infinity Max reconnect attempts
    delay number 2000 Initial delay (ms)
    maxDelay number 30000 Maximum delay cap (ms)
    exponential boolean true Use exponential backoff

    HeartbeatOptions

    Option Type Default Description
    message string | object 'ping' Payload sent as keep-alive
    interval number 30000 How often to ping (ms)
    timeout number 10000 Time to wait for pong before closing (ms)
    pongMessage string | object Expected server response to reset timeout

    Return Value (UseWebSocketReturn)

    Property Type Description
    readyState ReadyState Current connection state
    lastMessage MessageEvent | null Last raw message event received
    sendRaw(data) function Send a raw string or binary payload
    emit(channel, event, payload) function Send a structured { channel, event, payload } JSON message
    subscribe(channel, event, cb) function Register a listener. Returns an unsubscribe function
    unsubscribe(channel, event, cb) function Remove a specific listener
    connect() function Manually open/reconnect the connection
    disconnect() function Close the connection (prevents auto-reconnect)
    getWebSocket() function Access the underlying WebSocket instance

    useWebSocketEvent(channel, event, callback, connection?)

    Declarative hook that subscribes to a specific channel and event. Automatically cleans up on unmount.

    useWebSocketEvent('orders', 'status_update', (payload) => {
      console.log(`Order ${payload.orderId} is now ${payload.status}`);
    });
    Parameter Type Description
    channel string Channel name to listen on
    event string Event name to listen for
    callback (payload: T) => void Handler called with the event payload
    connection UseWebSocketReturn (Optional) Custom connection. If omitted, uses nearest <WebSocketProvider>

    <WebSocketProvider>

    React context provider that creates and shares a single WebSocket connection.

    <WebSocketProvider url="ws://localhost:8080" options={{ heartbeat: true }}>
      {children}
    </WebSocketProvider>
    Prop Type Description
    url string | () => string | Promise<string> WebSocket server URL
    options WebSocketOptions Same options as useWebSocket

    useSharedWebSocket()

    Access the shared connection created by the nearest <WebSocketProvider>. Returns the same UseWebSocketReturn shape as useWebSocket.

    const { emit, readyState, subscribe, disconnect } = useSharedWebSocket();

    ReadyState Enum

    Value Constant Meaning
    0 ReadyState.CONNECTING Socket is connecting
    1 ReadyState.OPEN Connection is open and ready
    2 ReadyState.CLOSING Connection is closing
    3 ReadyState.CLOSED Connection is closed
    -1 ReadyState.UNINSTANTIATED Hook mounted with manual: true, not yet connected

    Message Protocol

    When using emit() and subscribe(), all messages are serialized as JSON with this structure:

    interface WebSocketEventMessage<T = any> {
      channel: string;   // e.g. "chat:lobby", "market", "notifications"
      event: string;     // e.g. "new_message", "price_update", "alert"
      payload: T;        // any JSON-serializable data
    }

    Server-side, parse incoming messages as JSON and route by channel + event. Messages that don't match this structure are still delivered to the onMessage callback and lastMessage — so raw text and binary payloads work seamlessly alongside structured events.

    Example: Node.js Echo Server

    import { WebSocketServer } from 'ws';
    
    const wss = new WebSocketServer({ port: 8080 });
    
    wss.on('connection', (ws) => {
      ws.on('message', (data) => {
        const msg = data.toString();
    
        // Heartbeat
        if (msg === 'ping') {
          ws.send('pong');
          return;
        }
    
        // Parse structured message
        try {
          const parsed = JSON.parse(msg);
          const { channel, event, payload } = parsed;
    
          // Broadcast to all clients
          for (const client of wss.clients) {
            if (client.readyState === 1) {
              client.send(JSON.stringify({ channel, event, payload }));
            }
          }
        } catch {
          // Echo raw messages
          ws.send(`Echo: ${msg}`);
        }
      });
    });

    CDN Usage Example

    A complete standalone HTML page using react-websocket-kit from a CDN:

    <!DOCTYPE html>
    <html>
    <head>
      <title>CDN WebSocket Demo</title>
    </head>
    <body>
      <div id="root"></div>
    
      <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
      <script src="https://unpkg.com/react-websocket-kit/dist/index.umd.cjs"></script>
    
      <script type="text/babel">
        const { WebSocketProvider, useSharedWebSocket, useWebSocketEvent, ReadyState } = ReactWebSocketKit;
    
        function Chat() {
          const { emit, readyState } = useSharedWebSocket();
          const [messages, setMessages] = React.useState([]);
    
          useWebSocketEvent('chat', 'message', (payload) => {
            setMessages(prev => [...prev, payload]);
          });
    
          const send = () => {
            emit('chat', 'message', { text: 'Hello!', sender: 'CDN User' });
          };
    
          return (
            <div>
              <p>Status: {readyState === ReadyState.OPEN ? 'Connected' : 'Offline'}</p>
              <button onClick={send} disabled={readyState !== ReadyState.OPEN}>Send</button>
              <ul>
                {messages.map((m, i) => <li key={i}>{m.sender}: {m.text}</li>)}
              </ul>
            </div>
          );
        }
    
        function App() {
          return (
            <WebSocketProvider url="ws://localhost:8080">
              <Chat />
            </WebSocketProvider>
          );
        }
    
        ReactDOM.createRoot(document.getElementById('root')).render(<App />);
      </script>
    </body>
    </html>

    TypeScript

    All types are exported and available:

    import type {
      WebSocketOptions,
      WebSocketEventMessage,
      UseWebSocketReturn,
      ReconnectOptions,
      HeartbeatOptions,
      EventListenerCallback,
      WebSocketProviderProps,
    } from 'react-websocket-kit';

    License

    MIT