{"id":15254,"library":"unxhr","title":"unxhr: XMLHttpRequest Emulation for Node.js","description":"`unxhr` is a Node.js library that provides an emulation of the browser's native `XMLHttpRequest` object, enabling both synchronous and asynchronous HTTP requests within Node.js environments. Currently at version 1.2.0, its release cadence is moderate, with recent updates primarily focused on bug fixes and infrastructure improvements. The project is a fork of the original `XMLHttpRequest` package, specifically developed to achieve compliance with the XMLHttpRequest Level 2 specifications. Key differentiators include its complete lack of external dependencies, support for standard HTTP methods (GET, POST, PUT, DELETE), handling of binary data through JavaScript typed arrays, automatic redirection following, and limited support for the `file://` protocol. It serves as a bridge for codebases that expect browser-like XHR behavior in a Node.js context, despite some inherent limitations compared to a full browser implementation.","status":"active","version":"1.2.0","language":"javascript","source_language":"en","source_url":"git://github.com/mogztter/unxhr","tags":["javascript","xhr","ajax","sync","http"],"install":[{"cmd":"npm install unxhr","lang":"bash","label":"npm"},{"cmd":"yarn add unxhr","lang":"bash","label":"yarn"},{"cmd":"pnpm add unxhr","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary export is the `XMLHttpRequest` class, typically accessed as a property of the main CommonJS module export. While Node.js supports ESM, `unxhr` is primarily designed for and used with CommonJS `require` syntax.","wrong":"import { XMLHttpRequest } from 'unxhr';","symbol":"XMLHttpRequest","correct":"const XMLHttpRequest = require('unxhr').XMLHttpRequest;"},{"note":"The `XMLHttpRequest` symbol is a constructor and must be instantiated with the `new` keyword, similar to browser-based usage.","wrong":"const xhr = unxhr.XMLHttpRequest();","symbol":"XHR instance","correct":"const xhr = new XMLHttpRequest();"}],"quickstart":{"code":"const XMLHttpRequest = require('unxhr').XMLHttpRequest;\n\nasync function makeRequest() {\n  return new Promise((resolve, reject) => {\n    const xhr = new XMLHttpRequest();\n    xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true); // true for async\n\n    xhr.onreadystatechange = () => {\n      if (xhr.readyState === 4) {\n        if (xhr.status >= 200 && xhr.status < 300) {\n          try {\n            resolve(JSON.parse(xhr.responseText));\n          } catch (e) {\n            reject(new Error('Failed to parse JSON response: ' + e.message));\n          }\n        } else {\n          reject(new Error(`Request failed with status ${xhr.status}: ${xhr.statusText}`));\n        }\n      }\n    };\n\n    xhr.onerror = () => {\n      reject(new Error('Network error or connection refused.'));\n    };\n\n    xhr.send();\n  });\n}\n\nmakeRequest()\n  .then(data => console.log('Fetched data:', data))\n  .catch(error => console.error('Error during request:', error));\n\n// Example of a synchronous request (use with extreme caution due to blocking nature)\n// console.log('\\nStarting synchronous request (will block event loop)...');\n// const syncXhr = new XMLHttpRequest();\n// try {\n//   syncXhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1', false); // false for sync\n//   syncXhr.send(null);\n//   if (syncXhr.status === 200) {\n//     console.log('Synchronous Response:', JSON.parse(syncXhr.responseText));\n//   } else {\n//     console.error('Synchronous Error:', syncXhr.status, syncXhr.statusText);\n//   }\n// } catch (e) {\n//   console.error('Synchronous Request Failed:', e);\n// }\n// console.log('Synchronous request finished.');","lang":"javascript","description":"Demonstrates basic asynchronous HTTP GET request using `unxhr`'s `XMLHttpRequest` emulation, including event handling for response and errors, wrapped in a Promise."},"warnings":[{"fix":"Prioritize asynchronous requests whenever possible. If synchronous behavior is strictly required, ensure it's used in non-critical paths or dedicated worker threads to minimize impact on the main event loop.","message":"Synchronous requests using `unxhr` will block the entire Node.js event loop until a response is received. This behavior is inherent to synchronous XHR and can lead to unresponsive applications and performance issues.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always use asynchronous requests for scenarios requiring reliable HTTP header manipulation. If synchronous is unavoidable, thoroughly test header transmission.","message":"Synchronous requests in `unxhr` are known to have issues with properly setting and handling HTTP headers, potentially leading to incorrect request behavior or unexpected server responses.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For local file access, prefer Node.js's native `fs` module for reliable and robust file system interactions. Avoid `unxhr` for `file://` protocol access if file encoding or integrity is critical.","message":"Accessing local files via the `file://` protocol may produce unexpected results or errors, especially when dealing with files that are not encoded in UTF-8. There are known limitations in handling these scenarios.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Review the 'Known Issues / Missing Features' section in the package README. For advanced XHR features or a more complete HTTP client, consider using Node.js-native libraries like `node-fetch` or `axios`.","message":"The `unxhr` implementation is an emulation and does not provide a complete feature set identical to a browser's native `XMLHttpRequest`. Key missing features include certain events (e.g., `abort`), persistence of cookies between requests, and robust XML parsing support.","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":"Ensure you are using `const XMLHttpRequest = require('unxhr').XMLHttpRequest;` and that `XMLHttpRequest` is in scope where you are attempting to instantiate it.","cause":"The `XMLHttpRequest` class was not correctly imported or referenced before use.","error":"ReferenceError: XMLHttpRequest is not defined"},{"fix":"For `unxhr` v1.2.0 and above, the default `maxBuffer` is 100MB. If you encounter this, increase the buffer size by setting the `UNXHR_MAX_BUFFER` environment variable (e.g., `UNXHR_MAX_BUFFER=200000000` for 200MB).","cause":"The HTTP response body exceeded the maximum buffer size allocated for the internal child process communication. This typically happens with large responses in older versions or if `UNXHR_MAX_BUFFER` is set too low.","error":"Error: stdout maxBuffer exceeded. Did you mean to enable the sync option? Running an async process and expecting stdout to be captured. Consider increasing the maxBuffer option."},{"fix":"Verify network connectivity, check the target URL/host for correctness, and ensure no firewalls or proxies are blocking the request. Inspect the `onerror` event for more specific details if available.","cause":"The `onerror` callback was triggered, indicating a network-level issue such as no internet connection, an unreachable host, or a blocked port.","error":"Error: Network error or connection refused."}],"ecosystem":"npm"}