isomorphic-ws
A drop-in isomorphic WebSocket client that exposes one identical API in Node.js and browsers.
Repository Health
Technical Analysis
isomorphic-ws solves a small but common problem: Node.js has no built-in WebSocket implementation, while browsers ship a native WebSocket global with a different surface than the popular ws package. isomorphic-ws wraps both behind a single import so the same client code runs unmodified on the server and in the browser.
On Node it re-exports the ws package (installed as a peer dependency) directly. In a browser bundle it resolves to whichever global WebSocket (or MozWebSocket) implementation the environment provides. Bundlers pick the right file automatically via the browser field in package.json, so consumers just require('isomorphic-ws') or import WebSocket from 'isomorphic-ws' and get a working client either way.
What You Get
- A single
require('isomorphic-ws')/importthat resolves towson Node and the nativeWebSocketglobal in browsers - Automatic environment resolution via package.json’s
browserfield, so bundlers like Webpack and Rollup pick the right file with zero config - TypeScript definitions (
index.d.ts) that type the module as thewspackage’s WebSocket class - Fallback checks for
MozWebSocketalongside standardWebSocketfor older Firefox builds - Zero runtime dependencies of its own beyond the
wspeer dependency
Common Use Cases
- Writing a WebSocket client library that must work identically whether it’s imported in a Node.js backend or bundled into a browser frontend
- Building isomorphic/universal JavaScript apps (SSR frameworks, shared client SDKs) that establish WebSocket connections from either environment
- SDKs for realtime services (chat, live data feeds, blockchain nodes) that ship one client package instead of separate Node and browser builds
- Test suites that need to exercise WebSocket-dependent code under Node without swapping implementations manually
Under The Hood
Architecture
The entire package is two tiny entry files selected by package.json’s main/browser fields: node.js simply does module.exports = require('ws'), and browser.js probes WebSocket, MozWebSocket, global, window, and self in turn and exports whichever global constructor it finds. There is no shared internal module, no runtime configuration, and no abstraction layer beyond this environment dispatch — the design intentionally does as little as possible, delegating all actual WebSocket behavior to ws or the browser’s native implementation.
Tech Stack
The package has no dependencies of its own; it declares ws as a peerDependency ("ws": "*") that the consumer must install alongside it. It ships plain, unbundled JavaScript (CommonJS for Node, an ES module default export for the browser file) with a hand-written index.d.ts for TypeScript consumers, and the example/ directory shows both a Webpack and a Rollup build integrating the browser entry point. CI (CircleCI, .circleci/config.yml) only installs dependencies — it does not run a build or test step.
Code Quality
There are no test files anywhere in the repository, and the CI configuration confirms this — it caches node_modules but never invokes a test runner. Error handling is not applicable given the module’s scope (it either finds a WebSocket implementation or exports undefined/null). There are no linter or formatter configs, and the codebase is small enough (a few dozen lines total) that conventions are simple and consistent, but nothing here is verified by automated tests.
What Makes It Unique
The package’s value isn’t novel WebSocket behavior — it deliberately adds none — but a narrow, widely-adopted convention: the browser field swap that lets one import path silently become environment-appropriate code at bundle time. That pattern, combined with matching its API surface to ws so it’s compatible with existing Node WebSocket code, is why it’s become the de facto choice for libraries that need one WebSocket client for both server and browser bundles.
Used by 2 apps in this directory
Colanode
Knowledge Management · Team Chat · Collaboration
Local-first, self-hosted workspace that combines real-time chat, Notion-style pages, and structured databases — all synced via CRDTs so you work offline without losing a keystroke.
Uptime Kuma
Monitoring
Self-hosted monitoring for every service you run — 23 monitor types, 95 notification channels, live dashboards, and public status pages with no vendor lock-in.