Web ReadableStream to Node.js Readable Stream Converter
`readable-web-to-node-stream` is a utility package designed to seamlessly convert a Web-API `ReadableStream` (typically obtained from browser `fetch` responses or other Web Streams API sources) into a Node.js `Readable` stream. This conversion allows developers to process data originating from web contexts using familiar Node.js stream APIs and utilities, integrating browser-side streaming capabilities with Node.js backend processing. The current stable version is 5.0.0. The package maintains an active release cadence, frequently incorporating improvements and addressing breaking changes, notably the migration to a pure ECMAScript Module (ESM) in version 4.0.0. Key differentiators include its singular focus on this specific conversion direction, first-class TypeScript support, and a clear distinction from its complementary package for the reverse conversion. It targets modern JavaScript environments, requiring Node.js version 18 or newer.
Common errors
-
ERR_REQUIRE_ESM: require() of ES Module ... is not supported. Instead change the require of index.js in ... to a dynamic import() call.
cause Attempting to import the `readable-web-to-node-stream` package (which is pure ESM since v4.0.0) using CommonJS `require()` syntax in a Node.js environment older than v22 or without explicit ESM configuration.fixReplace `const { ReadableWebToNodeStream } = require('readable-web-to-node-stream');` with `import { ReadableWebToNodeStream } from 'readable-web-to-node-stream';`. Ensure your project is configured for ESM (e.g., `"type": "module"` in `package.json`) or upgrade to Node.js v22+ if you need CJS compatibility with ESM packages. -
ReferenceError: ReadableStream is not defined
cause The Web-API `ReadableStream` class is not available in the global scope where the code is executed. This typically happens in a pure Node.js environment without a browser-like global `fetch` API or a polyfill for web streams.fixEnsure you are running in a browser environment or in a Node.js environment where a global `fetch` API (which commonly provides `ReadableStream` on its response bodies) is available or explicitly polyfilled. For Node.js < 18, or if `fetch` is not globally available, you might need to use a package like `node-fetch` and/or `web-streams-polyfill`.
Warnings
- breaking The package migrated to a pure ECMAScript Module (ESM) in version 4.0.0. CommonJS `require()` is no longer directly supported in Node.js versions below 22, requiring changes to import statements.
- breaking The constructor option `propagateDestroy` was introduced in v5.0.0. Its default value is `false`. If set to `true`, destroying the Node.js stream will also cancel the underlying Web-API `ReadableStream`.
- gotcha The Node.js engine requirement was updated to `>= 18` starting from version 4.0.0. This package will not run on older Node.js versions.
- gotcha Multiple security vulnerabilities were addressed in dependencies (e.g., elliptic, y18n, ssri, lodash) in version 3.0.2. Older versions `<=3.0.1` may contain known vulnerabilities.
Install
-
npm install readable-web-to-node-stream -
yarn add readable-web-to-node-stream -
pnpm add readable-web-to-node-stream
Imports
- ReadableWebToNodeStream
const ReadableWebToNodeStream = require('readable-web-to-node-stream');import { ReadableWebToNodeStream } from 'readable-web-to-node-stream'; - ReadableWebToNodeStream (Type)
import type { ReadableWebToNodeStream } from 'readable-web-to-node-stream'; - All exports (namespace import)
import WebToNodeStream from 'readable-web-to-node-stream';
import * as WebToNodeStream from 'readable-web-to-node-stream';
Quickstart
import { ReadableWebToNodeStream } from 'readable-web-to-node-stream';
import { createWriteStream } from 'fs';
import { pipeline } from 'stream/promises';
async function downloadAndSave(url: string, filePath: string) {
console.log(`Downloading ${url} and saving to ${filePath}`);
// Ensure 'fetch' is available (global in browsers, or polyfilled/imported in Node.js < 18 or for specific use cases)
const response = await fetch(url);
if (!response.body) {
throw new Error('Response body is null. Cannot convert an empty body.');
}
const webReadableStream = response.body;
// Convert the Web-API ReadableStream to a Node.js Readable stream
const nodeStream = new ReadableWebToNodeStream(webReadableStream, { propagateDestroy: true });
// Pipe the Node.js stream to a file using stream.pipeline for robust error handling and cleanup
await pipeline(
nodeStream,
createWriteStream(filePath)
);
console.log(`Download complete: ${filePath}`);
}
// Example usage: Downloads a small dummy file from a public URL
// Replace with a suitable URL for actual testing. For local testing, a simple text file is good.
const exampleUrl = 'https://raw.githubusercontent.com/Borewit/readable-web-to-node-stream/master/package.json';
const outputFilePath = './downloaded-package.json';
downloadAndSave(exampleUrl, outputFilePath)
.catch(error => console.error('An error occurred during download:', error));