{"id":16279,"library":"xrs","title":"XRS Reactive Server","description":"xrs is a JavaScript library designed for building reactive servers and clients, currently at version 1.2.2. It facilitates full-duplex communication by treating both client requests and server responses as streams, promises, or plain values. The server component integrates the Express framework for routing and μWS (uws) for high-performance WebSocket handling, enabling efficient management of both HTTP and WebSocket connections. A key differentiator is its emphasis on stream-based interactions, allowing complex real-time data flows and supporting features like binary uploads with progress event tracking. The client-side library is designed to be lightweight, bundling at approximately 3 KB. While specific release cadence information is not provided, the current version suggests it is either actively maintained or stable. It's suitable for applications requiring low-latency, real-time communication with built-in stream processing capabilities.","status":"active","version":"1.2.2","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","reactive","server","express","uws"],"install":[{"cmd":"npm install xrs","lang":"bash","label":"npm"},{"cmd":"yarn add xrs","lang":"bash","label":"yarn"},{"cmd":"pnpm add xrs","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used internally as the underlying HTTP server framework for the xrs server.","package":"express","optional":false},{"reason":"Used internally for high-performance WebSocket communication on the xrs server.","package":"uws","optional":false}],"imports":[{"note":"`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.","wrong":"import { xrs } from 'xrs'; // xrs is the default export\nconst server = require('xrs')().listen(3000); // Incorrect CJS usage or server startup","symbol":"xrs","correct":"import xrs from 'xrs';\nconst server = xrs({ port: 3000, processor: req => 'ack' });"},{"note":"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.","wrong":"import { send } from 'xrs'; // `send` is returned by xrs(), not a named export\nconst send = xrs().connect('ws://localhost:3000'); // Incorrect method chaining","symbol":"xrs","correct":"import xrs from 'xrs';\nconst send = xrs('ws://localhost:3000');"},{"note":"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.","wrong":"import { http } from 'xrs'; // Not directly exported\nxrsServer.listen(3000); // Incorrectly assuming xrsServer has a direct .listen method","symbol":"xrsServer.http","correct":"import xrs from 'xrs';\nconst xrsServer = xrs({ port: 3000, processor: req => 'ack' });\nxrsServer.http.on('listening', () => console.log('Server is live'));"}],"quickstart":{"code":"import xrs from 'xrs';\nimport http from 'http'; // For server closing\n\nasync function runXRSExample() {\n  const serverPort = 4000; // Choose a specific port\n\n  // 1. Start the XRS Server\n  // The 'xrs' function can take a processor or an options object.\n  // We pass options to specify the port.\n  const xrsServer = xrs({\n    port: serverPort,\n    processor: (req) => {\n      console.log(`[Server] Received data from client (id: ${req.id}):`, req.data.toString());\n      if (req.data === 'trigger-error') {\n        throw new Error('Simulated server error');\n      }\n      return `Echo: ${req.data.toString()}`; // Send back a response\n    }\n  });\n\n  // Access the underlying HTTP server instance to confirm it's listening\n  // and for clean shutdown.\n  await new Promise<void>(resolve => {\n    xrsServer.http.on('listening', () => {\n      console.log(`[Server] XRS server running on ws://localhost:${serverPort}`);\n      resolve();\n    });\n  });\n\n  // 2. Initialize the XRS Client\n  // Pass the server URL to connect.\n  const send = xrs(`ws://localhost:${serverPort}`);\n\n  // 3. Client sends a simple value\n  console.log('[Client] Sending \"Hello Reactive Server!\"');\n  const clientResponseStream1 = await send('Hello Reactive Server!');\n  clientResponseStream1.on('data', (data) => {\n    console.log('[Client] Received response:', data);\n  });\n  clientResponseStream1.on('error', (err) => {\n    console.error('[Client] Error on stream 1:', err);\n  });\n\n  // 4. Client sends a binary stream with progress events\n  const binaryBuffer = Buffer.from('This is a test binary payload for upload.');\n  console.log('[Client] Sending binary data...');\n  const results: any[] = [];\n  const clientResponseStream2 = await send(binaryBuffer, { metadata: 'binary-upload' });\n  clientResponseStream2\n    .on('sent', d => results.push({ type: 'sent', value: d }))\n    .on('progress', d => results.push({ type: 'progress', value: d }))\n    .on('data', d => results.push({ type: 'complete', value: d }));\n\n  clientResponseStream2.on('end', () => {\n    console.log('[Client] Binary upload events:', results);\n  });\n\n  // 5. Client sends a promise that resolves\n  console.log('[Client] Sending a Promise that resolves...');\n  const promiseResponseStream = await send(Promise.resolve('Data from Promise'));\n  promiseResponseStream.on('data', (data) => {\n    console.log('[Client] Received response for Promise:', data);\n  });\n\n  // Wait a bit, then close the server\n  setTimeout(() => {\n    console.log('[Server] Shutting down XRS server.');\n    xrsServer.http.close(() => {\n      console.log('[Server] XRS server closed.');\n    });\n  }, 3000);\n}\n\nrunXRSExample().catch(console.error);","lang":"typescript","description":"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."},"warnings":[{"fix":"Always specify a `port` in the options object (e.g., `{ port: 3000, processor: ... }`) for predictable server startup and client connectivity.","message":"If the `port` option is omitted when creating an XRS server, it will default to a random available HTTP port. This can make client connection unpredictable.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"To enable HTTPS, provide the `certs` option with `key` and `cert` properties (e.g., `{ certs: { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem') }, ... }`).","message":"By default, the XRS server runs over HTTP. To enable HTTPS (secure communication), explicit SSL certificates must be provided in the server options.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure all client-side streams returned by `send` have an `.on('error', handler)` listener. On the server, ensure that any promises returned by the `processor` function are caught, and any streams created within it also handle errors robustly.","message":"Forgetting to attach `.on('error', handler)` listeners to streams (both client-side responses and server-side processor outputs) can lead to unhandled promise rejections or silent failures, especially with asynchronous operations.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Choose a different port for your XRS server, or identify and terminate the process currently using the conflicting port.","cause":"The specified server port is already in use by another process on the system.","error":"Error: listen EADDRINUSE :::<port_number>"},{"fix":"Ensure 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)`.","cause":"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.","error":"TypeError: xrs is not a function"},{"fix":"On 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.","cause":"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.","error":"UnhandledPromiseRejectionWarning: A promise was rejected with a reason that was not handled."}],"ecosystem":"npm"}