Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
xrs
✓ import xrs from 'xrs';
const server = xrs({ port: 3000, processor: req => 'ack' });
✗ import { xrs } from 'xrs'; // xrs is the default export
const server = require('xrs')().listen(3000); // Incorrect CJS usage or server startup
`xrs` is the default export. When called with an object containing a `processor` function or just a `processor` function, it configures and starts the XRS server.
xrs
✓ import xrs from 'xrs';
const send = xrs('ws://localhost:3000');
✗ import { send } from 'xrs'; // `send` is returned by xrs(), not a named export
const send = xrs().connect('ws://localhost:3000'); // Incorrect method chaining
The default export `xrs`, when called with a URL string (or without arguments for a default local connection), returns the client-side `send` function used to send data to the server.
xrsServer.http
✓ import xrs from 'xrs';
const xrsServer = xrs({ port: 3000, processor: req => 'ack' });
xrsServer.http.on('listening', () => console.log('Server is live'));
✗ import { http } from 'xrs'; // Not directly exported
xrsServer.listen(3000); // Incorrectly assuming xrsServer has a direct .listen method
The underlying Node.js `http` (or `https`) server instance is exposed as a property on the object returned by the server-side `xrs` call, allowing direct interaction with the core HTTP server API for events like 'listening' or for manual closing.
This quickstart demonstrates setting up an XRS server on a specific port, connecting an XRS client, sending various data types (string, binary, promise), and handling server responses and progress events.
import xrs from 'xrs';
import http from 'http'; // For server closing
async function runXRSExample() {
const serverPort = 4000; // Choose a specific port
// 1. Start the XRS Server
// The 'xrs' function can take a processor or an options object.
// We pass options to specify the port.
const xrsServer = xrs({
port: serverPort,
processor: (req) => {
console.log(`[Server] Received data from client (id: ${req.id}):`, req.data.toString());
if (req.data === 'trigger-error') {
throw new Error('Simulated server error');
}
return `Echo: ${req.data.toString()}`; // Send back a response
}
});
// Access the underlying HTTP server instance to confirm it's listening
// and for clean shutdown.
await new Promise<void>(resolve => {
xrsServer.http.on('listening', () => {
console.log(`[Server] XRS server running on ws://localhost:${serverPort}`);
resolve();
});
});
// 2. Initialize the XRS Client
// Pass the server URL to connect.
const send = xrs(`ws://localhost:${serverPort}`);
// 3. Client sends a simple value
console.log('[Client] Sending "Hello Reactive Server!"');
const clientResponseStream1 = await send('Hello Reactive Server!');
clientResponseStream1.on('data', (data) => {
console.log('[Client] Received response:', data);
});
clientResponseStream1.on('error', (err) => {
console.error('[Client] Error on stream 1:', err);
});
// 4. Client sends a binary stream with progress events
const binaryBuffer = Buffer.from('This is a test binary payload for upload.');
console.log('[Client] Sending binary data...');
const results: any[] = [];
const clientResponseStream2 = await send(binaryBuffer, { metadata: 'binary-upload' });
clientResponseStream2
.on('sent', d => results.push({ type: 'sent', value: d }))
.on('progress', d => results.push({ type: 'progress', value: d }))
.on('data', d => results.push({ type: 'complete', value: d }));
clientResponseStream2.on('end', () => {
console.log('[Client] Binary upload events:', results);
});
// 5. Client sends a promise that resolves
console.log('[Client] Sending a Promise that resolves...');
const promiseResponseStream = await send(Promise.resolve('Data from Promise'));
promiseResponseStream.on('data', (data) => {
console.log('[Client] Received response for Promise:', data);
});
// Wait a bit, then close the server
setTimeout(() => {
console.log('[Server] Shutting down XRS server.');
xrsServer.http.close(() => {
console.log('[Server] XRS server closed.');
});
}, 3000);
}
runXRSExample().catch(console.error);
Errors
Common errors & fixes
Error: listen EADDRINUSE :::<port_number>
The specified server port is already in use by another process on the system.
fixChoose a different port for your XRS server, or identify and terminate the process currently using the conflicting port.
TypeError: xrs is not a function
This typically occurs when attempting to call `xrs` after an incorrect CommonJS `require` (e.g., `const { xrs } = require('xrs')`) or when trying to use the client-side `xrs` return value as a server constructor.
fixEnsure correct CommonJS/ESM import: `const xrs = require('xrs')` or `import xrs from 'xrs'`. For server creation, use `const server = xrs(processor)` or `const server = xrs({ port, processor })`. For client, use `const send = xrs(url)`. UnhandledPromiseRejectionWarning: A promise was rejected with a reason that was not handled.
A Promise returned by the server's processor function or emitted by a client-side stream was rejected without an attached `.catch()` handler or an `.on('error', handler)` listener.
fixOn the server, ensure all Promises returned from the processor function are resolved or explicitly caught. On the client, always attach an `.on('error', handler)` to the stream returned by `send` to handle potential errors from the server. Audit
Dependencies
expressrequiredUsed internally as the underlying HTTP server framework for the xrs server.
uwsrequiredUsed internally for high-performance WebSocket communication on the xrs server.