mrkeyoor.com_
Wed 23 Sept 00:34 UTC
npmUtilsupdated 22 Sept 2026

into-stream review

into-stream 9.1.0 wraps a string, promise, iterable, async iterable, byte view, ArrayBuffer, web `ReadableStream`, or object in a Node.js `Readable`. The new feature in 9.1 is direct web `ReadableStream` input. Binary mode converts typed-array views to `Uint8Array`; `intoStream.object()` keeps JavaScript values as object-mode chunks. Its small API is useful at boundaries where another Node library insists on a stream. It does not read files, buffer an existing stream, or make browser streams portable, and the package now requires Node 20 or newer.

Verdict

Our install of into-stream 9.1.0 took 0.6 seconds, left a single 1 MB package with no audit findings, and passed Node 22 import checks while the browser build failed. Add it for Node 20+ adapter code that repeatedly turns values or iterables into `Readable` streams; use native constructors when one line already covers the input.

We installed it

Lab card: what happened when we installed into-streamScreenshot of into-stream documentation
Install✓ · 0.6s1 package on disk · 1 MB
ImportESM import works · require() works · ESM package with exports map
Browsern/acould not be bundled for the browser (Node-only code, most likely)
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does into-stream install cleanly?

Yes. In a fresh container with an empty cache, npm install into-stream finished in 0.6s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.

Can into-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 into-stream work with both ESM and CommonJS?

Yes. Both import 'into-stream' and require('into-stream') worked in Node 22 in our run. The package is published as ESM with an exports map.

Does into-stream include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

into-stream or readable-stream: which should you use?

readable-stream: Use readable-stream when a package needs the userland Node streams implementation and support across older runtimes. Our install of into-stream 9.1.0 took 0.6 seconds, left a single 1 MB package with no audit findings, and passed Node 22 import checks while the browser build failed.

When should you not use into-stream?

You need browser code: our esbuild browser bundle failed because the package imports node:stream, and the README describes a Node Readable result

API stability4/5Version 9.1.0 still exposes one default function plus its `.object` method, so the callable surface is easy to contain. Major releases do carry real platform changes: version 9 raised the minimum to Node 20 and changed the documented binary vocabulary from Buffer to Uint8Array, while version 8 stopped splitting plain strings into smaller chunks. Pin the major when chunk boundaries or an older Node runtime are part of the contract.
Docs4/5The README states every accepted input family, separates binary and object mode, says that backpressure is handled, and names the `child_process` stdio limitation. Version 9.1 release notes identify web `ReadableStream` support directly. The documentation is short because the API is short, but it leaves details such as array copying, promise rejection timing, falsy values, and typed-array conversion to the source and tests.
Maintenance4/5Version 9.1.0 was published and the repository was pushed on February 2, 2026. That release added web `ReadableStream` input five months after the Node 20 major. The repository is not archived, and GitHub currently reports 0 open issues and pull requests. The small codebase reduces maintenance surface, though its runtime policy follows modern Node versions and can force major upgrades for older services.
Ecosystem4/5npm counted 5,129,998 downloads in the latest measured week despite the repository having only 213 stars, a pattern consistent with a small transitive utility rather than a destination framework. It has 0 runtime dependencies, accepts standard iterable and stream shapes, and returns a normal Node `Readable`. Its ecosystem reach stops at the Node boundary because the browser build failed and the output is not a web stream.

Use it if

  • A Node API expects a `Readable`, but your source is already a string, bytes, promise, iterable, or web `ReadableStream`
  • You want an async iterable to respect Node stream backpressure without writing a custom `Readable` implementation
  • You need object-mode chunks from objects or object iterables through the explicit `intoStream.object()` entry point
  • Your supported runtime is Node 20 or newer and a default ESM import fits the codebase
Skip it if

Setup reality

We installed into-stream 9.1.0 in 0.6 seconds, and it left 1 package using 1 MB on disk. The published package was 24 KB unpacked, with 0 direct dependencies, 0 peer dependencies, bundled TypeScript declarations, and no npm audit findings. Both require() and ESM import worked in our Node 22 sandbox.

The package has no credentials, native build, or config file. It declares Node 20 as its minimum and imports node:stream; our browser build failed in esbuild for that reason. The output is always a Node Readable, including when version 9.1.0 receives a web ReadableStream. Browser-only code should stay on the web streams API.

Choose binary or object mode before wrapping the value. intoStream() accepts strings and byte-like chunks, while intoStream.object() is for arbitrary objects. Arrays are copied first, and each array element becomes one chunk. A promise is awaited inside the stream; if it rejects, consumers receive a stream error rather than a synchronous exception.

Backpressure is handled through Readable.from() and the internal async generator. Chunk boundaries still depend on the input: an iterable yields one chunk per element, while a plain string is yielded as one value. The README calls out one hard limit: these generated streams do not work as child_process stdio handles. Use an actual file stream when spawning a program that needs file input.

Patterns

Pipe a string into a Node destination stream-a-string

import intoStream from 'into-stream';

intoStream('hello
').pipe(process.stdout);

Since version 8, a plain string is yielded as one value; do not depend on the wrapper splitting it into smaller chunks.

Wrap bytes as a readable stream stream-byte-array

const bytes = new Uint8Array([72, 101, 108, 108, 111]);
const readable = intoStream(bytes);

Version 9 documents Uint8Array rather than Buffer as the binary input. Node Buffers are Uint8Array subclasses, but portable code can use the broader type.

Convert an ArrayBuffer to a Node stream stream-array-buffer

const response = await fetch(url);
const body = await response.arrayBuffer();
const readable = intoStream(body);

The package converts ArrayBuffer and typed-array views to Uint8Array before yielding them. The complete buffer is already in memory.

Delay the input behind a promise stream-a-promise

const readable = intoStream(loadPayload());

readable.on('error', (error) => {
  console.error('payload failed', error);
});
readable.pipe(destination);

A rejected promise becomes an asynchronous stream error. Attach error handling before consumption starts.

Turn a generator into chunks stream-an-iterable

function* lines() {
  yield 'first
';
  yield 'second
';
}

const readable = intoStream(lines());

Each iterable element is a chunk. Yield strings or byte views in binary mode, and do not assume adjacent chunks will stay separate downstream.

Wrap an async generator with backpressure stream-an-async-iterable

async function* rows() {
  for (const id of ids) {
    yield `${await loadRow(id)}
`;
  }
}

const readable = intoStream(rows());

The internal `Readable.from()` requests values as the consumer drains them, so the generator should keep cleanup logic in `finally` for early destruction.

Adapt a web ReadableStream in version 9.1 stream-web-readable

const response = await fetch(url);
if (!response.body) throw new Error('Missing response body');

const nodeReadable = intoStream(response.body);

Version 9.1.0 added this input. The result is a Node `Readable`, and our browser bundling attempt failed because `node:stream` is required.

Emit records in object mode stream-objects

const records = [{id: 1}, {id: 2}];
const readable = intoStream.object(records);

readable.on('data', (record) => {
  console.log(record.id);
});

Use `.object()` for arbitrary values. Passing objects to the binary function can trigger Node chunk-type errors during consumption.

Finish a pipeline with promise error handling pipe-with-promises

import {pipeline} from 'node:stream/promises';

await pipeline(
  intoStream(chunks),
  transform,
  destination,
);

`pipeline()` propagates source, transform, and destination failures and tears down the chain; plain `.pipe()` does not give one completion promise.

Consume the generated readable asynchronously consume-with-for-await

for await (const chunk of intoStream(['a', 'b', 'c'])) {
  console.log(chunk.toString());
}

Node may expose string chunks as Buffer values depending on the consumer path. Decode at the boundary instead of assuming a JavaScript string.

Destroy a stream when a request aborts cancel-stream-work

const readable = intoStream(source);

signal.addEventListener('abort', () => {
  readable.destroy(signal.reason);
}, {once: true});

Destroying the readable stops future reads, but cancellation of the underlying async iterable depends on whether its iterator implements `return()` and cleanup.

Use a file stream for child process input avoid-child-stdio

import {createReadStream} from 'node:fs';
import {spawn} from 'node:child_process';

const child = spawn('gzip', ['-c'], {
  stdio: [createReadStream('input.txt'), 'pipe', 'inherit'],
});

The into-stream README says its returned streams cannot be passed as `child_process` stdio entries. A real file stream is the documented alternative.

Alternatives

PackageRegistryPick it when
readable-streamnpmUse readable-stream when a package needs the userland Node streams implementation and support across older runtimes.
from2npmUse from2 when you need to implement a custom pull function instead of wrapping an existing iterable or value.
streamifiernpmUse streamifier only for its older Buffer and string API when maintaining a compatible legacy codebase.
get-streamnpmUse get-stream for the opposite direction: collecting a readable stream into text, bytes, or an array.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · 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.