Skip to content

thehashton/Tether

Repository files navigation

Tether

A resilient WebSocket client that holds on when the connection stretches.

By Harry Ashton

GitHub · npm · Live demo

Node 22+ TypeScript Zero runtime dependencies MIT License


Tether is a zero-dependency TypeScript WebSocket client built for production failure modes: dropped connections, slow networks, forced disconnects, and auth expiry — without falling over.

Like a tether, it stays linked. Messages queue while offline, replay in order on reconnect, and back off with full jitter until the socket is open again.

Live demo

A control-panel UI exercises every resilience feature in real time — reconnection, backoff, queue drain, bufferedAmount backpressure, multiplexing, and auth refresh.

tether-demo-wheat.vercel.app — or run locally. Deployed on Vercel with WebSocket Functions (public beta).

What it proves

Reconnection Full-jitter exponential backoff with live attempt + delay telemetry
Backpressure Queue flush pauses on real socket.bufferedAmount — not a synthetic rate limiter
Multiplexing Multiple logical channels over one physical WebSocket
Auth refresh Token rotation over the existing open socket — no disconnect

Getting started

Clone the monorepo and install:

git clone git@github.com:thehashton/Tether.git
cd Tether
pnpm install
pnpm build
pnpm test

Project layout

packages/tether-ws   →  client library (npm: tether-ws)
apps/demo            →  Next.js demo + WebSocket server

Use the library

npm install tether-ws
import { TetherClient } from 'tether-ws';

const client = new TetherClient({
  url: 'wss://example.com/ws',
  auth: { getToken: () => fetch('/api/token').then((r) => r.text()) },
});

client.on('reconnecting', ({ attempt, delayMs }) => {
  console.log(`retry #${attempt} in ${delayMs}ms`);
});

client.connect();
client.send({ hello: 'world' }, { channel: 'chat' });
client.subscribe('chat', (msg) => console.log(msg));

Full API reference → packages/tether-ws/README.md

Run the demo

cd apps/demo
cp .env.local.example .env.local
pnpm dev

Open http://localhost:3000.

Command What it does
pnpm dev Standalone WebSocket server on :3001 + Next.js UI
pnpm dev:vercel Vercel runtime with native WebSocket upgrade

Try Kill connection → watch backoff + queue replay. Flood 500 messages → inbound backpressure counter climbs. Force token refresh → auth rotates without a close event.

Deploy on Vercel

  1. Import the repo and set Root Directory to apps/demo
  2. Ensure Fluid Compute is enabled (default on new projects)
  3. Deploy — the WebSocket route lives at app/api/ws/route.ts via experimental_upgradeWebSocket()

License

MIT © Harry Ashton

About

A WebSocket client that handles the parts everyone glosses over — reconnection, backpressure, multiplexing, token refresh — plus a demo you can break on purpose.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors