mrkeyoor.com_
Wed 23 Sept 00:35 UTC
npmWeb Frontendupdated 22 Sept 2026

vite-compatible-readable-stream review

vite-compatible-readable-stream 3.6.1 is a fork of readable-stream 3.6 whose circular imports were rearranged for Rollup and Vite production builds. It carries the Node-style Readable, Writable, Duplex, Transform, PassThrough, `pipeline`, and `finished` APIs, and its 2-sentence README names `vite-plugin-shim-react-pdf` as the expected consumer. Our browser-target check still failed, so this is a narrow dependency workaround that must be tested in the exact Vite graph, not a general browser-stream recommendation.

Verdict

vite-compatible-readable-stream 3.6.1 installed in 0.8 seconds and left 5 packages using 1 MB in our sandbox, but our browser bundle failed despite the fork's Vite-focused purpose. Install it only for a reproduced dependency-specific workaround that passes your complete production build; use native Web Streams or `node:stream` for new code.

We installed it

Lab card: what happened when we installed vite-compatible-readable-streamScreenshot of vite-compatible-readable-stream documentation
Install✓ · 0.8s5 packages on disk · 1 MB
ImportESM import works · require() works · CommonJS package
Browsern/acould not be bundled for the browser (Node-only code, most likely)
Typesno TypeScript types found
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does vite-compatible-readable-stream install cleanly?

Yes. In a fresh container with an empty cache, npm install vite-compatible-readable-stream finished in 0.8s, leaving 5 packages and 1 MB on disk. npm audit reported no known vulnerabilities.

Can vite-compatible-readable-stream run in a browser?

Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.

Does vite-compatible-readable-stream work with both ESM and CommonJS?

Yes. Both import 'vite-compatible-readable-stream' and require('vite-compatible-readable-stream') worked in Node 22 in our run. The package is published as CommonJS.

Does vite-compatible-readable-stream include TypeScript types?

No type declarations were found in our install, so TypeScript users need their own declarations.

vite-compatible-readable-stream or readable-stream: which should you use?

readable-stream: Use the maintained userland Node stream mirror when your bundler accepts its module graph. vite-compatible-readable-stream 3.6.1 installed in 0.8 seconds and left 5 packages using 1 MB in our sandbox, but our browser bundle failed despite the fork's Vite-focused purpose.

When should you not use vite-compatible-readable-stream?

You are writing new browser stream code. Native ReadableStream and WritableStream follow the web platform instead of emulating Node's older stream model.

API stability4/5Version 3.6.1 retains the readable-stream 3 surface: 5 core classes plus `pipeline` and `finished`, with familiar event, pipe, destroy, and backpressure behavior. No package update has changed that API since April 2022. Predictability comes from being frozen, though, and callers do not receive newer Node stream methods, promise helpers, or web-stream conversion APIs.
Docs2/5The package README contains 2 substantive sentences: it says circular dependencies were refactored for Rollup/Vite and names `vite-plugin-shim-react-pdf`. It offers no alias example, supported Vite versions, export reference, browser limitations, test matrix, TypeScript note, or migration path. The linked Node stream manual documents today's runtime API and therefore includes features this readable-stream 3.6 fork may not have.
Maintenance2/5npm version 3.6.1 and the repository's latest push both date to April 21, 2022. The repository is not archived and GitHub's combined counter shows 0 open issues and pull requests. A small compatibility patch can remain unchanged when its target stays fixed, but 4 years without releases gives no evidence that current Vite, Rollup, esbuild, browsers, or Node stream changes are tested.
Ecosystem3/5The npm endpoint counted 5,013,387 downloads in the latest completed week, while the repository has 6 stars. High package traffic likely comes from dependency graphs rather than direct adoption; the README identifies just 1 expected plugin. Consumers inherit readable-stream concepts and 3 small dependencies, but there is no documented extension ecosystem and no first-party TypeScript declaration file.

Use it if

  • A specific Vite production graph fails on readable-stream circular imports and that graph can be redirected to this fork.
  • `vite-plugin-shim-react-pdf` or another fixed dependency path explicitly expects this package name and readable-stream 3 behavior.
  • An unchangeable dependency imports Node stream classes in browser code and the complete application build proves this fork works there.
  • Callback-based `pipeline` and `finished`, async iteration, and `Readable.from` from the readable-stream 3 era are the required contract.
Skip it if

Setup reality

We installed vite-compatible-readable-stream 3.6.1 in 0.8 seconds in a fresh Node 22 container. npm left 5 packages and 1 MB on disk. The package is 208 KB unpacked, declares 3 direct dependencies and 0 peers, has no bundled TypeScript declarations, and produced 0 audit findings. require() and ESM import both worked through CommonJS interoperability. Our direct esbuild browser build failed and emitted no bundle.

There are no credentials, native builds, or config files. The integration normally happens through a Vite alias or a plugin's dependency redirect rather than direct application imports. That makes the full production dependency graph the test target. The README promises fixed circular dependencies for Rollup and Vite, but our import * browser check did not compile. Confirm both development and production builds, then exercise actual PDF or stream behavior instead of treating installation success as browser proof.

The package depends on inherits, string_decoder, and util-deprecate. It exposes Node stream semantics, including byte/object high-water marks, flowing mode, backpressure, destruction, and callback completion. Native Web Streams are different objects with different readers, writers, and cancellation rules. This fork does not include modern conversion helpers or node:stream/promises. Attach error listeners before work begins and prefer pipeline() over a bare pipe chain when several stages must be destroyed together.

Version 3.6.1 declares Node 6+ but was published on April 21, 2022, the same day as the repository's latest push. The repository is unarchived with 0 open issues and pull requests, yet there is no release history after the fork landed. Remove the alias once the upstream dependency builds cleanly. Keeping a frozen compatibility layer after its triggering bug disappears leaves old stream behavior and an untyped package in the frontend graph.

Patterns

Load classes from CommonJS import-stream-classes

const { Readable, Writable, Transform, PassThrough } = require('vite-compatible-readable-stream');

Version 3.6.1 is CommonJS without an exports map. ESM import worked in Node 22.23.2 through interoperability, but bundler behavior still needs testing.

Implement a finite readable source create-readable

const { Readable } = require('vite-compatible-readable-stream');

let sent = false;
const source = new Readable({
  read() {
    if (sent) return;
    sent = true;
    this.push('first\n');
    this.push('second\n');
    this.push(null);
  },
});

`_read` may be called more than once, so retain state to avoid duplicate chunks. `push(null)` marks the end.

Create a readable from an iterable read-from-iterable

const { Readable } = require('vite-compatible-readable-stream');

const source = Readable.from(['alpha', 'beta', 'gamma']);

This fork includes `Readable.from`, with a browser-specific substituted module. Test it in the same production build that consumes the stream.

Consume UTF-8 chunks in flowing mode consume-data-events

source.setEncoding('utf8');
source.on('error', (error) => console.error(error));
source.on('data', (chunk) => console.log(chunk));
source.on('end', () => console.log('done'));

Adding a data listener starts flowing mode. Register the error listener first so a source failure does not become uncaught.

Iterate chunks asynchronously consume-async-iterator

for await (const chunk of source) {
  console.log(chunk.toString());
}

The runtime needs `Symbol.asyncIterator`. Exiting the loop early destroys the readable under readable-stream 3 behavior.

Apply writable backpressure create-writable

const { Writable } = require('vite-compatible-readable-stream');

const sink = new Writable({
  write(chunk, encoding, callback) {
    saveChunk(chunk).then(() => callback(), callback);
  },
});

Invoke the callback exactly once. Holding it until asynchronous storage finishes is what prevents the source from outrunning this sink.

Uppercase each chunk create-transform

const { Transform } = require('vite-compatible-readable-stream');

const upper = new Transform({
  transform(chunk, encoding, callback) {
    callback(null, chunk.toString().toUpperCase());
  },
});

Pass a failure as the callback's first argument. An error thrown later in unrelated asynchronous work is not captured automatically.

Transform JavaScript objects use-object-mode

const { Transform } = require('vite-compatible-readable-stream');

const pickId = new Transform({
  objectMode: true,
  transform(user, encoding, callback) { callback(null, user.id); },
});

Object mode counts buffered objects instead of bytes and uses its own high-water-mark default.

Pipe through one transform pipe-streams

source.pipe(upper).pipe(sink);

A pipe chain carries backpressure, but a destination error may leave another stage alive. Use `pipeline()` when teardown across stages matters.

Connect stages with coordinated cleanup pipeline-with-callback

const { pipeline } = require('vite-compatible-readable-stream');

pipeline(source, upper, sink, (error) => {
  if (error) console.error('pipeline failed', error);
  else console.log('pipeline complete');
});

This is the callback API. The package does not ship `node:stream/promises`, so leaving off the callback does not return the modern promise form.

Observe writable completion wait-for-finish

const { finished } = require('vite-compatible-readable-stream');

const stopWatching = finished(sink, (error) => {
  if (error) console.error(error);
  else console.log('sink closed');
});

`finished` reports errors and premature close as well as success. Call the returned cleanup if the observer is no longer needed.

Destroy a stream with a cause destroy-on-error

source.on('error', (cause) => console.error(cause.message));
source.destroy(new Error('input rejected'));

The passed error is emitted asynchronously. Without an error listener, it can terminate the process as an uncaught exception.

Alternatives

PackageRegistryPick it when
readable-streamnpmUse the maintained userland Node stream mirror when your bundler accepts its module graph.
stream-browserifynpmUse it when a browser build expects the conventional Browserify replacement for Node's stream module.
web-streams-polyfillnpmUse it for WHATWG Web Streams on a runtime that lacks the native classes.
vite-plugin-node-polyfillsnpmUse it when a Vite application needs several Node core shims and you accept that larger compatibility layer.

More web frontend guides

postcss · react · react-dom · tailwindcss · htmlparser2 · tailwind-merge · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.