npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

smart-ws

v0.1.3

Published

A resilient, type-safe WebSocket client with auto-reconnect, heartbeat, offline buffering, and lifecycle

Readme

smart-ws ⭐

A resilient, type-safe WebSocket client with auto-reconnect, heartbeat, offline buffering, and lifecycle events.

A lightweight, drop-in replacement for the native WebSocket API — designed for production-grade real-time applications.


🔗 Links

| Resource | Link | | :--- | :--- | | 📦 npm | https://www.npmjs.com/package/smart-ws | | 💻 GitHub | https://github.com/akpante3/smart-ws | | ** Front End: DEMO** | https://github.com/akpante3/FE-smart-ws-demo


🚀 Introduction

smart-ws is a fully-featured WebSocket client that fixes the biggest problems developers face when working with real-time connections:

  • WebSockets disconnect unexpectedly
  • Heartbeat logic must be manually implemented
  • Reconnection logic is repetitive
  • Offline mode breaks apps
  • Messages sent while disconnected get lost
  • No simple way to track connection status, retries, or latency
  • No type safety for incoming/outgoing messages

smart-ws solves all of these problems with a modern, minimal, TypeScript-first API.

If you’ve ever written code like this:

const ws = new WebSocket(url);

ws.onclose = () => {
  setTimeout(() => {
    ws = new WebSocket(url);
  }, 1000);
};

This library replaces all of the above with a single clean implementation.

🌟 Features

✔ Automatic Reconnect (with exponential backoff) Configurable options include:

  • Retry limits

  • Min/max delays

  • Exponential growth factor

  • Jitter to prevent reconnection storms

✔ Heartbeat / Ping-Pong Detection Prevents silent disconnections and detects dead connections. Tracks:

  • Latency (ms)

  • Last ping timestamp

  • Last pong timestamp

✔ Offline Queue / Message Buffer

  • When disconnected (or offline):

  • Outbound messages are buffered

  • Buffer is replayed on reconnect

  • Queue size limits & drop strategies supported

✔ Full Lifecycle Events

  • Listen to everything from connection status to buffering:

  • open, message, close, error, reconnect, ping, pong, online, offline, bufferAdd, bufferFlush.

✔ Type-Safe API (TypeScript)

  • Define exactly what your app sends/receives:
type Inbound = { type: "chat"; text: string; user: string; timestamp: number } | any;
type Outbound = { type: "chat"; text: string; user: string } | any;

No more guessing or manual type-casting.

✔ Works in Browser & Node.js

Node support via a simple constructor option: createWebSocket: (url) => new WebSocket(url).

✔ Tiny, dependency-free, production-tested

🧠 Why this library exists

In almost every real-time system (chat, trading dashboards, multiplayer apps, IoT dashboards), developers copy-paste the same fragile logic:

  • manual reconnect

  • setInterval pings

  • random JSON parsing

  • buffering messages

  • browser offline detection

smart-ws provides a reusable, reliable engine so your application code stays clean and focused on business logic.

🏗 Architecture Overview

SmartSocket │ ├── Connection Manager
│ - open/close lifecycle
│ - WebSocket constructor wrapper
│ ├── Reconnect Manager
│ - exponential backoff
│ - jitter
│ - retry counting
│ ├── Heartbeat Manager
│ - ping interval
│ - pong timeout
│ - latency calculation
│ ├── Buffer Manager
│ - offline queue
│ - flush on reconnect
│ └── EventEmitter
- on/off/emit
- lifecycle events

This is:

  • fully framework-agnostic

  • not tied to any UI library

  • not using anything React-specific

  • just a JavaScript class + events

This means it works with:

  • Vue

  • React

  • Svelte

  • Angular

  • SolidJS

  • Vanilla JS

  • Node.js

  • Electron

  • Bun

  • Cloudflare Workers

📦 Installation

# npm
npm install smart-ws
# yarn
yarn add smart-ws
# pnpm
pnpm add smart-ws

🎉 Quick Start

If you don't want to define strict message types yet, you can make your WebSocket fully flexible by using:

smart-ws does not care what your message looks like.(Inbound, Outbound)

You can send:

  • strings

  • numbers

  • objects

  • arrays

  • any JSON structure

  • multiple message types

  • commands, actions, events, payloads

  • completely custom protocols


import SmartSocket from "smart-ws";

// Allow any shape of inbound/outbound message
type Inbound = any;
type Outbound = any;

const ws = new SmartSocket<Inbound, Outbound>("ws://localhost:8080", {
  reconnect: {
    minDelay: 500,
    maxDelay: 8000,
    factor: 2,
    jitter: 0.2,
  },
  heartbeat: {
    interval: 30000,
    timeout: 5000,
    message: "ping",  // or any custom object
  },
  json: true          // ensures objects are auto-JSON encoded/decoded
});

// Listen for connection events
ws.on("open", () => console.log("Connected"));
ws.on("close", () => console.log("Disconnected"));
ws.on("reconnect", (attempt) => console.log("Reconnecting… attempt:", attempt));

// Listen for messages (any shape)
ws.on("message", (data) => {
  console.log("Incoming:", data);
});

// Send any JSON value
ws.send({
  event: "hello",
  payload: { text: "Hello from smart-ws!" }
});

⚙️ Configuration Options

| Export | Description | | ---------------- | --------------------------------------------------- | | Option | Controls automatic re-connect behavior | | heartbeat | Ping-pong settings for detecting dead connections | | buffer | Offline message queue settings. | | json | Enable/disable automatic JSON.stringify JSON parse. | | createWebSocket| Required in Node.js to provide the WebSocket implementation. |

Reconnect

Controls automatic re-connect behavior (exponential backoff with jitter).

    {
        retries: Infinity,   // how many times to retry (Infinity recommended)
        minDelay: 500,       // initial delay (ms)
        maxDelay: 15000,     // maximum delay (ms)
        factor: 2,           // exponential factor
        jitter: 0.2          // +/- 20% random variance
    }

Heartbeat

Configuration for the ping-pong mechanism.

    {
        interval: 25000,     // send ping every 25s (ms)
        timeout: 5000,       // wait 5s for a pong (ms)
        message: "ping",     // or your custom object if json: true
        enabled: true
    }

Buffer (offline queue)

{
  enabled: true,
  max: 200,              // max stored messages
  dropStrategy: "oldest" // drop "oldest" when full (or "newest")
}

CreateWebSocket (Node.js Support)

Required in Node.js environments to supply a WebSocket implementation (e.g., the ws library).

import WS from "ws";

const ws = new SmartSocket(url, {
  createWebSocket: (url) => new WS(url)
});

🧩 Full Event API

Listen to lifecycle events using ws.on(event, handler).

| Event | Description | Handler Signature | | :--- | :--- | :--- | | open | Connection opened successfully. | () => void | | close | Closed by server or client. | () => void | | error | WebSocket error occurred. | (error: Event) => void | | message | Incoming message received. | (msg: Inbound) => void | | reconnect | Reconnect attempt initiated. | (attempt: number) => void | | ping | Heartbeat ping message sent. | (latency: number) => void | | pong | Heartbeat pong message received. | (latency: number) => void | | online | Browser regained internet (via window.ononline). | () => void | | offline | Browser lost internet (via window.onoffline). | () => void | | bufferAdd | Message added to the offline buffer. | (message: Outbound) => void | | bufferFlush | Buffered messages are being sent upon reconnect. | (count: number) => void |

💡 Use Cases

smart-ws is ideal for any application that requires a robust, always-on connection:

  • Real-time chat (Slack/Discord-style)

  • Trading dashboards & Crypto tickers

  • Multiplayer games

  • IoT device monitoring

  • Collaboration tools & Live analytics dashboards

  • Push notification systems & Social feeds

  • Background agents (Node.js)

💬 Example: Real-Time Group Chat

For a complete, working example using smart-ws in a group chat scenario:

Demo repository: 👉 https://github.com/your-username/smart-ws-demo

Live demo: 👉 https://your-demo-link.com

🔍 Runtime Status API

Access the current state of the connection at any time:

ws.getStatus();     // string: "open", "closed", "connecting", "reconnecting", "error"
ws.getRetries();    // number: current reconnect attempt
ws.getLatency();    // number: last ping/pong latency (ms)
ws.getLastPing();   // number: timestamp of last ping
ws.getLastPong();   // number: timestamp of last pong

💼 Production Tips

  • Always enable heartbeat in production to prevent silent disconnections.

  • Prefer json: true for clarity, type safety, and automatic parsing.

  • Set a meaningful maxDelay for reconnect (e.g., 15-60 seconds) to avoid stressing the server.

  • Use buffer.max to prevent potential memory leaks in long-running offline scenarios.

  • Track reconnect attempts and getStatus() for UI visibility to inform the user.

🛠 Development / Contributing

# Build (compiles TypeScript to JS)
npm run build

# Watch mode (for development)
npm run dev

# Publish to npm
npm publish --access public

Pull requests are welcome! Feel free to open an issue to discuss major changes.

📄 License

MIT © 2025 Victor Obije