Post

After implementing web streams in multiple runtimes, supporting them for years, talking with other implementers, dealing with issues... I think it's well past time we talked about something better blog.cloudflare.com/a-better-web...

blog.cloudflare.comWe deserve a better streams API for JavaScriptThe Web streams API has become ubiquitous in JavaScript runtimes but was designed for a different era. Here's what a modern streaming API could (should?) look like.

29 reposts83 likes

Hard agree that current Web Streams are a pain. Just streaming chunks of UTF-8 encoded strings into a Response is slow and a lot od code because of that. But one question: why Uint8Array[] ? it’s already an array?

Need to know boundaries of each chunk no? Like right now a chunk can be any value in web streams so you can think of this as batching up multiple of those values so you only pay the promise cost across the chunks rather than 1 by 1.

But it’s a an AsyncIterable<Uint8Array[]> ? I must be missing something obvious, as the blog also says “Instead of yielding one chunk per iteration, streams yield Uint8Array[]: arrays of chunks. This amortizes the async overhead across multiple chunks”

But I don’t get why one chunk isn’t just one large Uint8Array. Why is each chunk a Uint8Array[] ? Perhaps it’s more efficient to use a plain array to batch a few things together you get from the source?

I'm confused by this example. If you say these streams are pull-based only, wouldn't the first write() "block" the promise because nothing is reading it yet, so await would never progress and never reach the `Stream.text` line?

Ah nvm I guess that's why you have actual pull stream below. This was confusing because up until that point, and in the comments of this example you were talking about backpressure and how nothing is written/transformed until a reader pulls it, but then you show an API that does buffering.

Can we please avoid custom cleanup methods in new APIs? Symbol.dispose is amazing, and while HTML spec hasn't integrated it into the variety of existing APIs it has, it would be great to leverage it in any new API designs.

One final piece of feedback is that I'd still like to see some BYOB mechanism. I agree the existing one is not great - I was eagerly awaiting it (no pun intended 😅) all the way throughout design until it turned out to be completely useless for Wasm, and I would *love* to see a proper alternative.

One aspect of the Web Streams I quite like is that it's transferrable. Would that new API also be? I use it quite a lot to transform async generators running in a worker and consumed on main thread.