Isomorphic WebSocket implementation that works across Node.js and browser environments
npx @tessl/cli install tessl/npm-isomorphic-ws@5.0.0Isomorphic WebSocket provides a unified WebSocket interface that works seamlessly across Node.js and browser environments. It acts as a compatibility layer that uses the 'ws' package in Node.js and falls back to native WebSocket APIs in browsers, enabling developers to write WebSocket code once and run it everywhere.
npm install isomorphic-ws wsNote: Both isomorphic-ws and ws must be installed, as ws is a peer dependency required for Node.js functionality.
const WebSocket = require('isomorphic-ws');ES Modules:
import WebSocket from 'isomorphic-ws';import WebSocket from 'isomorphic-ws';
// Create WebSocket connection
const ws = new WebSocket('wss://echo.websocket.org/');
// Set up event handlers
ws.onopen = function open() {
console.log('Connected to WebSocket server');
ws.send('Hello Server!');
};
ws.onmessage = function incoming(event) {
console.log('Received:', event.data);
};
ws.onclose = function close() {
console.log('Connection closed');
};
ws.onerror = function error(err) {
console.error('WebSocket error:', err);
};Isomorphic WebSocket uses environment detection to provide the appropriate WebSocket implementation:
Creates a new WebSocket connection with isomorphic compatibility.
/**
* Create a new WebSocket connection
* @param {string} url - WebSocket server URL (ws:// or wss://)
* @param {string|string[]} [protocols] - Optional subprotocol(s)
* @param {object} [options] - Options (Node.js only, ignored in browsers)
* @returns {WebSocket} WebSocket instance
*/
new WebSocket(url, protocols?, options?)Usage Example:
// Basic connection
const ws = new WebSocket('wss://echo.websocket.org/');
// With subprotocols
const ws = new WebSocket('wss://example.com/', ['protocol1', 'protocol2']);
// With options (Node.js only)
const ws = new WebSocket('wss://example.com/', {
headers: { 'User-Agent': 'MyApp/1.0' }
});Properties available on WebSocket instances, following the standard WebSocket API.
/**
* Current connection state
* @type {number} 0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED
*/
ws.readyState
/**
* WebSocket server URL
* @type {string}
*/
ws.url
/**
* Selected subprotocol
* @type {string}
*/
ws.protocol
/**
* Bytes queued for transmission
* @type {number}
*/
ws.bufferedAmount
/**
* Negotiated extensions
* @type {string}
*/
ws.extensions
/**
* Binary data type ('blob' or 'arraybuffer')
* @type {string}
*/
ws.binaryTypeMethods available on WebSocket instances for controlling the connection and sending data.
/**
* Send data through the WebSocket connection
* @param {string|Buffer|ArrayBuffer|Blob} data - Data to send
*/
ws.send(data)
/**
* Close the WebSocket connection
* @param {number} [code] - Close code (1000 = normal closure)
* @param {string} [reason] - Reason for closing
*/
ws.close(code?, reason?)
/**
* Add event listener
* @param {string} type - Event type ('open', 'close', 'message', 'error')
* @param {function} listener - Event handler function
*/
ws.addEventListener(type, listener)
/**
* Remove event listener
* @param {string} type - Event type
* @param {function} listener - Event handler function to remove
*/
ws.removeEventListener(type, listener)
/**
* Dispatch event
* @param {Event} event - Event to dispatch
* @returns {boolean} true if event was handled
*/
ws.dispatchEvent(event)Event handler properties for WebSocket lifecycle events.
/**
* Connection opened event handler
* @type {function|null}
*/
ws.onopen = function(event) { /* handle open */ }
/**
* Connection closed event handler
* @type {function|null}
*/
ws.onclose = function(event) {
// event.code - close code
// event.reason - close reason
// event.wasClean - boolean indicating clean close
}
/**
* Message received event handler
* @type {function|null}
*/
ws.onmessage = function(event) {
// event.data - received data (string, Buffer, ArrayBuffer, etc.)
}
/**
* Error event handler
* @type {function|null}
*/
ws.onerror = function(event) {
// event.error - error object (Node.js)
// In browsers, error details may be limited
}Static constants defining connection states.
/**
* Connection state constants
*/
WebSocket.CONNECTING = 0 // Connection is being established
WebSocket.OPEN = 1 // Connection is open and ready
WebSocket.CLOSING = 2 // Connection is closing
WebSocket.CLOSED = 3 // Connection is closedIn Node.js, isomorphic-ws re-exports the 'ws' package, providing access to all its features:
In browsers, isomorphic-ws uses the native WebSocket implementation:
Common error scenarios and handling patterns:
const ws = new WebSocket('wss://example.com/');
ws.onerror = function(event) {
// Connection errors, network issues, etc.
console.error('WebSocket error occurred');
};
ws.onclose = function(event) {
if (!event.wasClean) {
// Connection closed unexpectedly
console.log('Connection lost, attempting to reconnect...');
}
};
// Handle connection timeout
const connectionTimeout = setTimeout(() => {
if (ws.readyState === WebSocket.CONNECTING) {
ws.close();
console.error('Connection timeout');
}
}, 10000);
ws.onopen = function() {
clearTimeout(connectionTimeout);
};Full TypeScript support is provided via type definitions:
import WebSocket from 'isomorphic-ws';
// Type-safe WebSocket usage
const ws: WebSocket = new WebSocket('wss://example.com/');
ws.onmessage = (event: MessageEvent) => {
const data: string = event.data;
console.log('Received:', data);
};Requirements:
@types/ws for full type support