[whatwg/streams] Revisiting ReadableStream.from(syncIter) and ReadableStream.from(str) (Issue #1376)

jasnell created an issue (whatwg/streams#1376)

### What is the issue with the Streams Standard?

I know this has been discussed a number of times before but I would very much appreciate if we could revisit whether passing a sync iterable, string/single value to a `ReadableStream.from` would be possible.

Specifically, in reviewing real world code, it's become evident that the following is actually a fairly common usage pattern as awful as it is:

```js
const rs = new ReadableStream({
  start(controller) {
    controller.enqueue(aSingleChunkOfSomething);
    controller.close();
  }
});
```

Then using the `ReadableStream` as part of a component in a larger rendering pipeline. The fundamental issue with this is that it's actually fairly difficult to optimize around since we are forced to allocate the `controller`, handle the `start` call and resulting microtask, etc.

It's also fairly common to seed a `ReadableStream` with an existing in memory data source like an array:

```js
const chunks = [1,2,3];
const rs = new ReadableStream({
  pull(controller) {
    let chunk = chunks.shift();
    if (chunk !== undefined) {
      controller.enqueue(chunk);
    } else {
      controller.close();
    }
  }
});
```

We could provide more optimizations internally for cases like this by allowing `ReadableStream.from(...)` to accept a single value and/or sync iterator... Passing a string or BufferSource as a single value would special case in that they would not be treated as sync iterators:

```js
ReadableStream.from('hello');  // yields only a single string 'hello' then closes
ReadableStream.from(new Uint8Array(10));  // yields only the single Uint8Array
ReadableStream.from([1,2,3]);  // yields 1, 2, then 3, then closes
```

This eliminates a significant amount of boilerplate and gives an opportunity to optimize by avoiding allocation of the underlying controller and not having to worry about user code grabbing and retaining a reference to the `controller`. It also means avoiding having to call out to the `start` and `pull` algorithms and the associated mechanism around it. The fact that it is more ergonomic for users is just another benefit.

/cc @MattiasBuelens @lucacasonato

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/issues/1376
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/streams/issues/1376@github.com>

Received on Monday, 13 July 2026 17:56:55 UTC