• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Web Streams API
2
3<!--introduced_in=v16.5.0-->
4
5<!-- YAML
6added: v16.5.0
7changes:
8  - version: v18.0.0
9    pr-url: https://github.com/nodejs/node/pull/42225
10    description: Use of this API no longer emit a runtime warning.
11-->
12
13> Stability: 1 - Experimental.
14
15An implementation of the [WHATWG Streams Standard][].
16
17## Overview
18
19The [WHATWG Streams Standard][] (or "web streams") defines an API for handling
20streaming data. It is similar to the Node.js [Streams][] API but emerged later
21and has become the "standard" API for streaming data across many JavaScript
22environments.
23
24There are three primary types of objects:
25
26* `ReadableStream` - Represents a source of streaming data.
27* `WritableStream` - Represents a destination for streaming data.
28* `TransformStream` - Represents an algorithm for transforming streaming data.
29
30### Example `ReadableStream`
31
32This example creates a simple `ReadableStream` that pushes the current
33`performance.now()` timestamp once every second forever. An async iterable
34is used to read the data from the stream.
35
36```mjs
37import {
38  ReadableStream,
39} from 'node:stream/web';
40
41import {
42  setInterval as every,
43} from 'node:timers/promises';
44
45import {
46  performance,
47} from 'node:perf_hooks';
48
49const SECOND = 1000;
50
51const stream = new ReadableStream({
52  async start(controller) {
53    for await (const _ of every(SECOND))
54      controller.enqueue(performance.now());
55  },
56});
57
58for await (const value of stream)
59  console.log(value);
60```
61
62```cjs
63const {
64  ReadableStream,
65} = require('node:stream/web');
66
67const {
68  setInterval: every,
69} = require('node:timers/promises');
70
71const {
72  performance,
73} = require('node:perf_hooks');
74
75const SECOND = 1000;
76
77const stream = new ReadableStream({
78  async start(controller) {
79    for await (const _ of every(SECOND))
80      controller.enqueue(performance.now());
81  },
82});
83
84(async () => {
85  for await (const value of stream)
86    console.log(value);
87})();
88```
89
90## API
91
92### Class: `ReadableStream`
93
94<!-- YAML
95added: v16.5.0
96changes:
97  - version: v18.0.0
98    pr-url: https://github.com/nodejs/node/pull/42225
99    description: This class is now exposed on the global object.
100-->
101
102#### `new ReadableStream([underlyingSource [, strategy]])`
103
104<!-- YAML
105added: v16.5.0
106-->
107
108<!--lint disable maximum-line-length remark-lint-->
109
110* `underlyingSource` {Object}
111  * `start` {Function} A user-defined function that is invoked immediately when
112    the `ReadableStream` is created.
113    * `controller` {ReadableStreamDefaultController|ReadableByteStreamController}
114    * Returns: `undefined` or a promise fulfilled with `undefined`.
115  * `pull` {Function} A user-defined function that is called repeatedly when the
116    `ReadableStream` internal queue is not full. The operation may be sync or
117    async. If async, the function will not be called again until the previously
118    returned promise is fulfilled.
119    * `controller` {ReadableStreamDefaultController|ReadableByteStreamController}
120    * Returns: A promise fulfilled with `undefined`.
121  * `cancel` {Function} A user-defined function that is called when the
122    `ReadableStream` is canceled.
123    * `reason` {any}
124    * Returns: A promise fulfilled with `undefined`.
125  * `type` {string} Must be `'bytes'` or `undefined`.
126  * `autoAllocateChunkSize` {number} Used only when `type` is equal to
127    `'bytes'`. When set to a non-zero value a view buffer is automatically
128    allocated to `ReadableByteStreamController.byobRequest`. When not set
129    one must use stream's internal queues to transfer data via the default
130    reader `ReadableStreamDefaultReader`.
131* `strategy` {Object}
132  * `highWaterMark` {number} The maximum internal queue size before backpressure
133    is applied.
134  * `size` {Function} A user-defined function used to identify the size of each
135    chunk of data.
136    * `chunk` {any}
137    * Returns: {number}
138
139<!--lint enable maximum-line-length remark-lint-->
140
141#### `readableStream.locked`
142
143<!-- YAML
144added: v16.5.0
145-->
146
147* Type: {boolean} Set to `true` if there is an active reader for this
148  {ReadableStream}.
149
150The `readableStream.locked` property is `false` by default, and is
151switched to `true` while there is an active reader consuming the
152stream's data.
153
154#### `readableStream.cancel([reason])`
155
156<!-- YAML
157added: v16.5.0
158-->
159
160* `reason` {any}
161* Returns: A promise fulfilled with `undefined` once cancelation has
162  been completed.
163
164#### `readableStream.getReader([options])`
165
166<!-- YAML
167added: v16.5.0
168-->
169
170* `options` {Object}
171  * `mode` {string} `'byob'` or `undefined`
172* Returns: {ReadableStreamDefaultReader|ReadableStreamBYOBReader}
173
174```mjs
175import { ReadableStream } from 'node:stream/web';
176
177const stream = new ReadableStream();
178
179const reader = stream.getReader();
180
181console.log(await reader.read());
182```
183
184```cjs
185const { ReadableStream } = require('node:stream/web');
186
187const stream = new ReadableStream();
188
189const reader = stream.getReader();
190
191reader.read().then(console.log);
192```
193
194Causes the `readableStream.locked` to be `true`.
195
196#### `readableStream.pipeThrough(transform[, options])`
197
198<!-- YAML
199added: v16.5.0
200-->
201
202* `transform` {Object}
203  * `readable` {ReadableStream} The `ReadableStream` to which
204    `transform.writable` will push the potentially modified data
205    is receives from this `ReadableStream`.
206  * `writable` {WritableStream} The `WritableStream` to which this
207    `ReadableStream`'s data will be written.
208* `options` {Object}
209  * `preventAbort` {boolean} When `true`, errors in this `ReadableStream`
210    will not cause `transform.writable` to be aborted.
211  * `preventCancel` {boolean} When `true`, errors in the destination
212    `transform.writable` do not cause this `ReadableStream` to be
213    canceled.
214  * `preventClose` {boolean} When `true`, closing this `ReadableStream`
215    does not cause `transform.writable` to be closed.
216  * `signal` {AbortSignal} Allows the transfer of data to be canceled
217    using an {AbortController}.
218* Returns: {ReadableStream} From `transform.readable`.
219
220Connects this {ReadableStream} to the pair of {ReadableStream} and
221{WritableStream} provided in the `transform` argument such that the
222data from this {ReadableStream} is written in to `transform.writable`,
223possibly transformed, then pushed to `transform.readable`. Once the
224pipeline is configured, `transform.readable` is returned.
225
226Causes the `readableStream.locked` to be `true` while the pipe operation
227is active.
228
229```mjs
230import {
231  ReadableStream,
232  TransformStream,
233} from 'node:stream/web';
234
235const stream = new ReadableStream({
236  start(controller) {
237    controller.enqueue('a');
238  },
239});
240
241const transform = new TransformStream({
242  transform(chunk, controller) {
243    controller.enqueue(chunk.toUpperCase());
244  },
245});
246
247const transformedStream = stream.pipeThrough(transform);
248
249for await (const chunk of transformedStream)
250  console.log(chunk);
251```
252
253```cjs
254const {
255  ReadableStream,
256  TransformStream,
257} = require('node:stream/web');
258
259const stream = new ReadableStream({
260  start(controller) {
261    controller.enqueue('a');
262  },
263});
264
265const transform = new TransformStream({
266  transform(chunk, controller) {
267    controller.enqueue(chunk.toUpperCase());
268  },
269});
270
271const transformedStream = stream.pipeThrough(transform);
272
273(async () => {
274  for await (const chunk of transformedStream)
275    console.log(chunk);
276})();
277```
278
279#### `readableStream.pipeTo(destination[, options])`
280
281<!-- YAML
282added: v16.5.0
283-->
284
285* `destination` {WritableStream} A {WritableStream} to which this
286  `ReadableStream`'s data will be written.
287* `options` {Object}
288  * `preventAbort` {boolean} When `true`, errors in this `ReadableStream`
289    will not cause `destination` to be aborted.
290  * `preventCancel` {boolean} When `true`, errors in the `destination`
291    will not cause this `ReadableStream` to be canceled.
292  * `preventClose` {boolean} When `true`, closing this `ReadableStream`
293    does not cause `destination` to be closed.
294  * `signal` {AbortSignal} Allows the transfer of data to be canceled
295    using an {AbortController}.
296* Returns: A promise fulfilled with `undefined`
297
298Causes the `readableStream.locked` to be `true` while the pipe operation
299is active.
300
301#### `readableStream.tee()`
302
303<!-- YAML
304added: v16.5.0
305changes:
306  - version: v18.10.0
307    pr-url: https://github.com/nodejs/node/pull/44505
308    description: Support teeing a readable byte stream.
309-->
310
311* Returns: {ReadableStream\[]}
312
313Returns a pair of new {ReadableStream} instances to which this
314`ReadableStream`'s data will be forwarded. Each will receive the
315same data.
316
317Causes the `readableStream.locked` to be `true`.
318
319#### `readableStream.values([options])`
320
321<!-- YAML
322added: v16.5.0
323-->
324
325* `options` {Object}
326  * `preventCancel` {boolean} When `true`, prevents the {ReadableStream}
327    from being closed when the async iterator abruptly terminates.
328    **Default**: `false`.
329
330Creates and returns an async iterator usable for consuming this
331`ReadableStream`'s data.
332
333Causes the `readableStream.locked` to be `true` while the async iterator
334is active.
335
336```mjs
337import { Buffer } from 'node:buffer';
338
339const stream = new ReadableStream(getSomeSource());
340
341for await (const chunk of stream.values({ preventCancel: true }))
342  console.log(Buffer.from(chunk).toString());
343```
344
345#### Async Iteration
346
347The {ReadableStream} object supports the async iterator protocol using
348`for await` syntax.
349
350```mjs
351import { Buffer } from 'node:buffer';
352
353const stream = new ReadableStream(getSomeSource());
354
355for await (const chunk of stream)
356  console.log(Buffer.from(chunk).toString());
357```
358
359The async iterator will consume the {ReadableStream} until it terminates.
360
361By default, if the async iterator exits early (via either a `break`,
362`return`, or a `throw`), the {ReadableStream} will be closed. To prevent
363automatic closing of the {ReadableStream}, use the `readableStream.values()`
364method to acquire the async iterator and set the `preventCancel` option to
365`true`.
366
367The {ReadableStream} must not be locked (that is, it must not have an existing
368active reader). During the async iteration, the {ReadableStream} will be locked.
369
370#### Transferring with `postMessage()`
371
372A {ReadableStream} instance can be transferred using a {MessagePort}.
373
374```js
375const stream = new ReadableStream(getReadableSourceSomehow());
376
377const { port1, port2 } = new MessageChannel();
378
379port1.onmessage = ({ data }) => {
380  data.getReader().read().then((chunk) => {
381    console.log(chunk);
382  });
383};
384
385port2.postMessage(stream, [stream]);
386```
387
388### Class: `ReadableStreamDefaultReader`
389
390<!-- YAML
391added: v16.5.0
392changes:
393  - version: v18.0.0
394    pr-url: https://github.com/nodejs/node/pull/42225
395    description: This class is now exposed on the global object.
396-->
397
398By default, calling `readableStream.getReader()` with no arguments
399will return an instance of `ReadableStreamDefaultReader`. The default
400reader treats the chunks of data passed through the stream as opaque
401values, which allows the {ReadableStream} to work with generally any
402JavaScript value.
403
404#### `new ReadableStreamDefaultReader(stream)`
405
406<!-- YAML
407added: v16.5.0
408-->
409
410* `stream` {ReadableStream}
411
412Creates a new {ReadableStreamDefaultReader} that is locked to the
413given {ReadableStream}.
414
415#### `readableStreamDefaultReader.cancel([reason])`
416
417<!-- YAML
418added: v16.5.0
419-->
420
421* `reason` {any}
422* Returns: A promise fulfilled with `undefined`.
423
424Cancels the {ReadableStream} and returns a promise that is fulfilled
425when the underlying stream has been canceled.
426
427#### `readableStreamDefaultReader.closed`
428
429<!-- YAML
430added: v16.5.0
431-->
432
433* Type: {Promise} Fulfilled with `undefined` when the associated
434  {ReadableStream} is closed or rejected if the stream errors or the reader's
435  lock is released before the stream finishes closing.
436
437#### `readableStreamDefaultReader.read()`
438
439<!-- YAML
440added: v16.5.0
441-->
442
443* Returns: A promise fulfilled with an object:
444  * `value` {ArrayBuffer}
445  * `done` {boolean}
446
447Requests the next chunk of data from the underlying {ReadableStream}
448and returns a promise that is fulfilled with the data once it is
449available.
450
451#### `readableStreamDefaultReader.releaseLock()`
452
453<!-- YAML
454added: v16.5.0
455-->
456
457Releases this reader's lock on the underlying {ReadableStream}.
458
459### Class: `ReadableStreamBYOBReader`
460
461<!-- YAML
462added: v16.5.0
463changes:
464  - version: v18.0.0
465    pr-url: https://github.com/nodejs/node/pull/42225
466    description: This class is now exposed on the global object.
467-->
468
469The `ReadableStreamBYOBReader` is an alternative consumer for
470byte-oriented {ReadableStream}s (those that are created with
471`underlyingSource.type` set equal to `'bytes'` when the
472`ReadableStream` was created).
473
474The `BYOB` is short for "bring your own buffer". This is a
475pattern that allows for more efficient reading of byte-oriented
476data that avoids extraneous copying.
477
478```mjs
479import {
480  open,
481} from 'node:fs/promises';
482
483import {
484  ReadableStream,
485} from 'node:stream/web';
486
487import { Buffer } from 'node:buffer';
488
489class Source {
490  type = 'bytes';
491  autoAllocateChunkSize = 1024;
492
493  async start(controller) {
494    this.file = await open(new URL(import.meta.url));
495    this.controller = controller;
496  }
497
498  async pull(controller) {
499    const view = controller.byobRequest?.view;
500    const {
501      bytesRead,
502    } = await this.file.read({
503      buffer: view,
504      offset: view.byteOffset,
505      length: view.byteLength,
506    });
507
508    if (bytesRead === 0) {
509      await this.file.close();
510      this.controller.close();
511    }
512    controller.byobRequest.respond(bytesRead);
513  }
514}
515
516const stream = new ReadableStream(new Source());
517
518async function read(stream) {
519  const reader = stream.getReader({ mode: 'byob' });
520
521  const chunks = [];
522  let result;
523  do {
524    result = await reader.read(Buffer.alloc(100));
525    if (result.value !== undefined)
526      chunks.push(Buffer.from(result.value));
527  } while (!result.done);
528
529  return Buffer.concat(chunks);
530}
531
532const data = await read(stream);
533console.log(Buffer.from(data).toString());
534```
535
536#### `new ReadableStreamBYOBReader(stream)`
537
538<!-- YAML
539added: v16.5.0
540-->
541
542* `stream` {ReadableStream}
543
544Creates a new `ReadableStreamBYOBReader` that is locked to the
545given {ReadableStream}.
546
547#### `readableStreamBYOBReader.cancel([reason])`
548
549<!-- YAML
550added: v16.5.0
551-->
552
553* `reason` {any}
554* Returns: A promise fulfilled with `undefined`.
555
556Cancels the {ReadableStream} and returns a promise that is fulfilled
557when the underlying stream has been canceled.
558
559#### `readableStreamBYOBReader.closed`
560
561<!-- YAML
562added: v16.5.0
563-->
564
565* Type: {Promise} Fulfilled with `undefined` when the associated
566  {ReadableStream} is closed or rejected if the stream errors or the reader's
567  lock is released before the stream finishes closing.
568
569#### `readableStreamBYOBReader.read(view)`
570
571<!-- YAML
572added: v16.5.0
573-->
574
575* `view` {Buffer|TypedArray|DataView}
576* Returns: A promise fulfilled with an object:
577  * `value` {ArrayBuffer}
578  * `done` {boolean}
579
580Requests the next chunk of data from the underlying {ReadableStream}
581and returns a promise that is fulfilled with the data once it is
582available.
583
584Do not pass a pooled {Buffer} object instance in to this method.
585Pooled `Buffer` objects are created using `Buffer.allocUnsafe()`,
586or `Buffer.from()`, or are often returned by various `node:fs` module
587callbacks. These types of `Buffer`s use a shared underlying
588{ArrayBuffer} object that contains all of the data from all of
589the pooled `Buffer` instances. When a `Buffer`, {TypedArray},
590or {DataView} is passed in to `readableStreamBYOBReader.read()`,
591the view's underlying `ArrayBuffer` is _detached_, invalidating
592all existing views that may exist on that `ArrayBuffer`. This
593can have disastrous consequences for your application.
594
595#### `readableStreamBYOBReader.releaseLock()`
596
597<!-- YAML
598added: v16.5.0
599-->
600
601Releases this reader's lock on the underlying {ReadableStream}.
602
603### Class: `ReadableStreamDefaultController`
604
605<!-- YAML
606added: v16.5.0
607-->
608
609Every {ReadableStream} has a controller that is responsible for
610the internal state and management of the stream's queue. The
611`ReadableStreamDefaultController` is the default controller
612implementation for `ReadableStream`s that are not byte-oriented.
613
614#### `readableStreamDefaultController.close()`
615
616<!-- YAML
617added: v16.5.0
618-->
619
620Closes the {ReadableStream} to which this controller is associated.
621
622#### `readableStreamDefaultController.desiredSize`
623
624<!-- YAML
625added: v16.5.0
626-->
627
628* Type: {number}
629
630Returns the amount of data remaining to fill the {ReadableStream}'s
631queue.
632
633#### `readableStreamDefaultController.enqueue([chunk])`
634
635<!-- YAML
636added: v16.5.0
637-->
638
639* `chunk` {any}
640
641Appends a new chunk of data to the {ReadableStream}'s queue.
642
643#### `readableStreamDefaultController.error([error])`
644
645<!-- YAML
646added: v16.5.0
647-->
648
649* `error` {any}
650
651Signals an error that causes the {ReadableStream} to error and close.
652
653### Class: `ReadableByteStreamController`
654
655<!-- YAML
656added: v16.5.0
657changes:
658  - version: v18.10.0
659    pr-url: https://github.com/nodejs/node/pull/44702
660    description: Support handling a BYOB pull request from a released reader.
661-->
662
663Every {ReadableStream} has a controller that is responsible for
664the internal state and management of the stream's queue. The
665`ReadableByteStreamController` is for byte-oriented `ReadableStream`s.
666
667#### `readableByteStreamController.byobRequest`
668
669<!-- YAML
670added: v16.5.0
671-->
672
673* Type: {ReadableStreamBYOBRequest}
674
675#### `readableByteStreamController.close()`
676
677<!-- YAML
678added: v16.5.0
679-->
680
681Closes the {ReadableStream} to which this controller is associated.
682
683#### `readableByteStreamController.desiredSize`
684
685<!-- YAML
686added: v16.5.0
687-->
688
689* Type: {number}
690
691Returns the amount of data remaining to fill the {ReadableStream}'s
692queue.
693
694#### `readableByteStreamController.enqueue(chunk)`
695
696<!-- YAML
697added: v16.5.0
698-->
699
700* `chunk`: {Buffer|TypedArray|DataView}
701
702Appends a new chunk of data to the {ReadableStream}'s queue.
703
704#### `readableByteStreamController.error([error])`
705
706<!-- YAML
707added: v16.5.0
708-->
709
710* `error` {any}
711
712Signals an error that causes the {ReadableStream} to error and close.
713
714### Class: `ReadableStreamBYOBRequest`
715
716<!-- YAML
717added: v16.5.0
718changes:
719  - version: v18.0.0
720    pr-url: https://github.com/nodejs/node/pull/42225
721    description: This class is now exposed on the global object.
722-->
723
724When using `ReadableByteStreamController` in byte-oriented
725streams, and when using the `ReadableStreamBYOBReader`,
726the `readableByteStreamController.byobRequest` property
727provides access to a `ReadableStreamBYOBRequest` instance
728that represents the current read request. The object
729is used to gain access to the `ArrayBuffer`/`TypedArray`
730that has been provided for the read request to fill,
731and provides methods for signaling that the data has
732been provided.
733
734#### `readableStreamBYOBRequest.respond(bytesWritten)`
735
736<!-- YAML
737added: v16.5.0
738-->
739
740* `bytesWritten` {number}
741
742Signals that a `bytesWritten` number of bytes have been written
743to `readableStreamBYOBRequest.view`.
744
745#### `readableStreamBYOBRequest.respondWithNewView(view)`
746
747<!-- YAML
748added: v16.5.0
749-->
750
751* `view` {Buffer|TypedArray|DataView}
752
753Signals that the request has been fulfilled with bytes written
754to a new `Buffer`, `TypedArray`, or `DataView`.
755
756#### `readableStreamBYOBRequest.view`
757
758<!-- YAML
759added: v16.5.0
760-->
761
762* Type: {Buffer|TypedArray|DataView}
763
764### Class: `WritableStream`
765
766<!-- YAML
767added: v16.5.0
768changes:
769  - version: v18.0.0
770    pr-url: https://github.com/nodejs/node/pull/42225
771    description: This class is now exposed on the global object.
772-->
773
774The `WritableStream` is a destination to which stream data is sent.
775
776```mjs
777import {
778  WritableStream,
779} from 'node:stream/web';
780
781const stream = new WritableStream({
782  write(chunk) {
783    console.log(chunk);
784  },
785});
786
787await stream.getWriter().write('Hello World');
788```
789
790#### `new WritableStream([underlyingSink[, strategy]])`
791
792<!-- YAML
793added: v16.5.0
794-->
795
796* `underlyingSink` {Object}
797  * `start` {Function} A user-defined function that is invoked immediately when
798    the `WritableStream` is created.
799    * `controller` {WritableStreamDefaultController}
800    * Returns: `undefined` or a promise fulfilled with `undefined`.
801  * `write` {Function} A user-defined function that is invoked when a chunk of
802    data has been written to the `WritableStream`.
803    * `chunk` {any}
804    * `controller` {WritableStreamDefaultController}
805    * Returns: A promise fulfilled with `undefined`.
806  * `close` {Function} A user-defined function that is called when the
807    `WritableStream` is closed.
808    * Returns: A promise fulfilled with `undefined`.
809  * `abort` {Function} A user-defined function that is called to abruptly close
810    the `WritableStream`.
811    * `reason` {any}
812    * Returns: A promise fulfilled with `undefined`.
813  * `type` {any} The `type` option is reserved for future use and _must_ be
814    undefined.
815* `strategy` {Object}
816  * `highWaterMark` {number} The maximum internal queue size before backpressure
817    is applied.
818  * `size` {Function} A user-defined function used to identify the size of each
819    chunk of data.
820    * `chunk` {any}
821    * Returns: {number}
822
823#### `writableStream.abort([reason])`
824
825<!-- YAML
826added: v16.5.0
827-->
828
829* `reason` {any}
830* Returns: A promise fulfilled with `undefined`.
831
832Abruptly terminates the `WritableStream`. All queued writes will be
833canceled with their associated promises rejected.
834
835#### `writableStream.close()`
836
837<!-- YAML
838added: v16.5.0
839-->
840
841* Returns: A promise fulfilled with `undefined`.
842
843Closes the `WritableStream` when no additional writes are expected.
844
845#### `writableStream.getWriter()`
846
847<!-- YAML
848added: v16.5.0
849-->
850
851* Returns: {WritableStreamDefaultWriter}
852
853Creates and creates a new writer instance that can be used to write
854data into the `WritableStream`.
855
856#### `writableStream.locked`
857
858<!-- YAML
859added: v16.5.0
860-->
861
862* Type: {boolean}
863
864The `writableStream.locked` property is `false` by default, and is
865switched to `true` while there is an active writer attached to this
866`WritableStream`.
867
868#### Transferring with postMessage()
869
870A {WritableStream} instance can be transferred using a {MessagePort}.
871
872```js
873const stream = new WritableStream(getWritableSinkSomehow());
874
875const { port1, port2 } = new MessageChannel();
876
877port1.onmessage = ({ data }) => {
878  data.getWriter().write('hello');
879};
880
881port2.postMessage(stream, [stream]);
882```
883
884### Class: `WritableStreamDefaultWriter`
885
886<!-- YAML
887added: v16.5.0
888changes:
889  - version: v18.0.0
890    pr-url: https://github.com/nodejs/node/pull/42225
891    description: This class is now exposed on the global object.
892-->
893
894#### `new WritableStreamDefaultWriter(stream)`
895
896<!-- YAML
897added: v16.5.0
898-->
899
900* `stream` {WritableStream}
901
902Creates a new `WritableStreamDefaultWriter` that is locked to the given
903`WritableStream`.
904
905#### `writableStreamDefaultWriter.abort([reason])`
906
907<!-- YAML
908added: v16.5.0
909-->
910
911* `reason` {any}
912* Returns: A promise fulfilled with `undefined`.
913
914Abruptly terminates the `WritableStream`. All queued writes will be
915canceled with their associated promises rejected.
916
917#### `writableStreamDefaultWriter.close()`
918
919<!-- YAML
920added: v16.5.0
921-->
922
923* Returns: A promise fulfilled with `undefined`.
924
925Closes the `WritableStream` when no additional writes are expected.
926
927#### `writableStreamDefaultWriter.closed`
928
929<!-- YAML
930added: v16.5.0
931-->
932
933* Type: {Promise} Fulfilled with `undefined` when the associated
934  {WritableStream} is closed or rejected if the stream errors or the writer's
935  lock is released before the stream finishes closing.
936
937#### `writableStreamDefaultWriter.desiredSize`
938
939<!-- YAML
940added: v16.5.0
941-->
942
943* Type: {number}
944
945The amount of data required to fill the {WritableStream}'s queue.
946
947#### `writableStreamDefaultWriter.ready`
948
949<!-- YAML
950added: v16.5.0
951-->
952
953* type: A promise that is fulfilled with `undefined` when the
954  writer is ready to be used.
955
956#### `writableStreamDefaultWriter.releaseLock()`
957
958<!-- YAML
959added: v16.5.0
960-->
961
962Releases this writer's lock on the underlying {ReadableStream}.
963
964#### `writableStreamDefaultWriter.write([chunk])`
965
966<!-- YAML
967added: v16.5.0
968-->
969
970* `chunk`: {any}
971* Returns: A promise fulfilled with `undefined`.
972
973Appends a new chunk of data to the {WritableStream}'s queue.
974
975### Class: `WritableStreamDefaultController`
976
977<!-- YAML
978added: v16.5.0
979changes:
980  - version: v18.0.0
981    pr-url: https://github.com/nodejs/node/pull/42225
982    description: This class is now exposed on the global object.
983-->
984
985The `WritableStreamDefaultController` manage's the {WritableStream}'s
986internal state.
987
988#### `writableStreamDefaultController.error([error])`
989
990<!-- YAML
991added: v16.5.0
992-->
993
994* `error` {any}
995
996Called by user-code to signal that an error has occurred while processing
997the `WritableStream` data. When called, the {WritableStream} will be aborted,
998with currently pending writes canceled.
999
1000#### `writableStreamDefaultController.signal`
1001
1002* Type: {AbortSignal} An `AbortSignal` that can be used to cancel pending
1003  write or close operations when a {WritableStream} is aborted.
1004
1005### Class: `TransformStream`
1006
1007<!-- YAML
1008added: v16.5.0
1009changes:
1010  - version: v18.0.0
1011    pr-url: https://github.com/nodejs/node/pull/42225
1012    description: This class is now exposed on the global object.
1013-->
1014
1015A `TransformStream` consists of a {ReadableStream} and a {WritableStream} that
1016are connected such that the data written to the `WritableStream` is received,
1017and potentially transformed, before being pushed into the `ReadableStream`'s
1018queue.
1019
1020```mjs
1021import {
1022  TransformStream,
1023} from 'node:stream/web';
1024
1025const transform = new TransformStream({
1026  transform(chunk, controller) {
1027    controller.enqueue(chunk.toUpperCase());
1028  },
1029});
1030
1031await Promise.all([
1032  transform.writable.getWriter().write('A'),
1033  transform.readable.getReader().read(),
1034]);
1035```
1036
1037#### `new TransformStream([transformer[, writableStrategy[, readableStrategy]]])`
1038
1039<!-- YAML
1040added: v16.5.0
1041-->
1042
1043* `transformer` {Object}
1044  * `start` {Function} A user-defined function that is invoked immediately when
1045    the `TransformStream` is created.
1046    * `controller` {TransformStreamDefaultController}
1047    * Returns: `undefined` or a promise fulfilled with `undefined`
1048  * `transform` {Function} A user-defined function that receives, and
1049    potentially modifies, a chunk of data written to `transformStream.writable`,
1050    before forwarding that on to `transformStream.readable`.
1051    * `chunk` {any}
1052    * `controller` {TransformStreamDefaultController}
1053    * Returns: A promise fulfilled with `undefined`.
1054  * `flush` {Function} A user-defined function that is called immediately before
1055    the writable side of the `TransformStream` is closed, signaling the end of
1056    the transformation process.
1057    * `controller` {TransformStreamDefaultController}
1058    * Returns: A promise fulfilled with `undefined`.
1059  * `readableType` {any} the `readableType` option is reserved for future use
1060    and _must_ be `undefined`.
1061  * `writableType` {any} the `writableType` option is reserved for future use
1062    and _must_ be `undefined`.
1063* `writableStrategy` {Object}
1064  * `highWaterMark` {number} The maximum internal queue size before backpressure
1065    is applied.
1066  * `size` {Function} A user-defined function used to identify the size of each
1067    chunk of data.
1068    * `chunk` {any}
1069    * Returns: {number}
1070* `readableStrategy` {Object}
1071  * `highWaterMark` {number} The maximum internal queue size before backpressure
1072    is applied.
1073  * `size` {Function} A user-defined function used to identify the size of each
1074    chunk of data.
1075    * `chunk` {any}
1076    * Returns: {number}
1077
1078#### `transformStream.readable`
1079
1080<!-- YAML
1081added: v16.5.0
1082-->
1083
1084* Type: {ReadableStream}
1085
1086#### `transformStream.writable`
1087
1088<!-- YAML
1089added: v16.5.0
1090-->
1091
1092* Type: {WritableStream}
1093
1094#### Transferring with postMessage()
1095
1096A {TransformStream} instance can be transferred using a {MessagePort}.
1097
1098```js
1099const stream = new TransformStream();
1100
1101const { port1, port2 } = new MessageChannel();
1102
1103port1.onmessage = ({ data }) => {
1104  const { writable, readable } = data;
1105  // ...
1106};
1107
1108port2.postMessage(stream, [stream]);
1109```
1110
1111### Class: `TransformStreamDefaultController`
1112
1113<!-- YAML
1114added: v16.5.0
1115changes:
1116  - version: v18.0.0
1117    pr-url: https://github.com/nodejs/node/pull/42225
1118    description: This class is now exposed on the global object.
1119-->
1120
1121The `TransformStreamDefaultController` manages the internal state
1122of the `TransformStream`.
1123
1124#### `transformStreamDefaultController.desiredSize`
1125
1126<!-- YAML
1127added: v16.5.0
1128-->
1129
1130* Type: {number}
1131
1132The amount of data required to fill the readable side's queue.
1133
1134#### `transformStreamDefaultController.enqueue([chunk])`
1135
1136<!-- YAML
1137added: v16.5.0
1138-->
1139
1140* `chunk` {any}
1141
1142Appends a chunk of data to the readable side's queue.
1143
1144#### `transformStreamDefaultController.error([reason])`
1145
1146<!-- YAML
1147added: v16.5.0
1148-->
1149
1150* `reason` {any}
1151
1152Signals to both the readable and writable side that an error has occurred
1153while processing the transform data, causing both sides to be abruptly
1154closed.
1155
1156#### `transformStreamDefaultController.terminate()`
1157
1158<!-- YAML
1159added: v16.5.0
1160-->
1161
1162Closes the readable side of the transport and causes the writable side
1163to be abruptly closed with an error.
1164
1165### Class: `ByteLengthQueuingStrategy`
1166
1167<!-- YAML
1168added: v16.5.0
1169changes:
1170  - version: v18.0.0
1171    pr-url: https://github.com/nodejs/node/pull/42225
1172    description: This class is now exposed on the global object.
1173-->
1174
1175#### `new ByteLengthQueuingStrategy(options)`
1176
1177<!-- YAML
1178added: v16.5.0
1179-->
1180
1181* `options` {Object}
1182  * `highWaterMark` {number}
1183
1184#### `byteLengthQueuingStrategy.highWaterMark`
1185
1186<!-- YAML
1187added: v16.5.0
1188-->
1189
1190* Type: {number}
1191
1192#### `byteLengthQueuingStrategy.size`
1193
1194<!-- YAML
1195added: v16.5.0
1196-->
1197
1198* Type: {Function}
1199  * `chunk` {any}
1200  * Returns: {number}
1201
1202### Class: `CountQueuingStrategy`
1203
1204<!-- YAML
1205added: v16.5.0
1206changes:
1207  - version: v18.0.0
1208    pr-url: https://github.com/nodejs/node/pull/42225
1209    description: This class is now exposed on the global object.
1210-->
1211
1212#### `new CountQueuingStrategy(options)`
1213
1214<!-- YAML
1215added: v16.5.0
1216-->
1217
1218* `options` {Object}
1219  * `highWaterMark` {number}
1220
1221#### `countQueuingStrategy.highWaterMark`
1222
1223<!-- YAML
1224added: v16.5.0
1225-->
1226
1227* Type: {number}
1228
1229#### `countQueuingStrategy.size`
1230
1231<!-- YAML
1232added: v16.5.0
1233-->
1234
1235* Type: {Function}
1236  * `chunk` {any}
1237  * Returns: {number}
1238
1239### Class: `TextEncoderStream`
1240
1241<!-- YAML
1242added: v16.6.0
1243changes:
1244  - version: v18.0.0
1245    pr-url: https://github.com/nodejs/node/pull/42225
1246    description: This class is now exposed on the global object.
1247-->
1248
1249#### `new TextEncoderStream()`
1250
1251<!-- YAML
1252added: v16.6.0
1253-->
1254
1255Creates a new `TextEncoderStream` instance.
1256
1257#### `textEncoderStream.encoding`
1258
1259<!-- YAML
1260added: v16.6.0
1261-->
1262
1263* Type: {string}
1264
1265The encoding supported by the `TextEncoderStream` instance.
1266
1267#### `textEncoderStream.readable`
1268
1269<!-- YAML
1270added: v16.6.0
1271-->
1272
1273* Type: {ReadableStream}
1274
1275#### `textEncoderStream.writable`
1276
1277<!-- YAML
1278added: v16.6.0
1279-->
1280
1281* Type: {WritableStream}
1282
1283### Class: `TextDecoderStream`
1284
1285<!-- YAML
1286added: v16.6.0
1287changes:
1288  - version: v18.0.0
1289    pr-url: https://github.com/nodejs/node/pull/42225
1290    description: This class is now exposed on the global object.
1291-->
1292
1293#### `new TextDecoderStream([encoding[, options]])`
1294
1295<!-- YAML
1296added: v16.6.0
1297-->
1298
1299* `encoding` {string} Identifies the `encoding` that this `TextDecoder` instance
1300  supports. **Default:** `'utf-8'`.
1301* `options` {Object}
1302  * `fatal` {boolean} `true` if decoding failures are fatal.
1303  * `ignoreBOM` {boolean} When `true`, the `TextDecoderStream` will include the
1304    byte order mark in the decoded result. When `false`, the byte order mark
1305    will be removed from the output. This option is only used when `encoding` is
1306    `'utf-8'`, `'utf-16be'`, or `'utf-16le'`. **Default:** `false`.
1307
1308Creates a new `TextDecoderStream` instance.
1309
1310#### `textDecoderStream.encoding`
1311
1312<!-- YAML
1313added: v16.6.0
1314-->
1315
1316* Type: {string}
1317
1318The encoding supported by the `TextDecoderStream` instance.
1319
1320#### `textDecoderStream.fatal`
1321
1322<!-- YAML
1323added: v16.6.0
1324-->
1325
1326* Type: {boolean}
1327
1328The value will be `true` if decoding errors result in a `TypeError` being
1329thrown.
1330
1331#### `textDecoderStream.ignoreBOM`
1332
1333<!-- YAML
1334added: v16.6.0
1335-->
1336
1337* Type: {boolean}
1338
1339The value will be `true` if the decoding result will include the byte order
1340mark.
1341
1342#### `textDecoderStream.readable`
1343
1344<!-- YAML
1345added: v16.6.0
1346-->
1347
1348* Type: {ReadableStream}
1349
1350#### `textDecoderStream.writable`
1351
1352<!-- YAML
1353added: v16.6.0
1354-->
1355
1356* Type: {WritableStream}
1357
1358### Class: `CompressionStream`
1359
1360<!-- YAML
1361added: v17.0.0
1362changes:
1363  - version: v18.0.0
1364    pr-url: https://github.com/nodejs/node/pull/42225
1365    description: This class is now exposed on the global object.
1366-->
1367
1368#### `new CompressionStream(format)`
1369
1370<!-- YAML
1371added: v17.0.0
1372-->
1373
1374* `format` {string} One of either `'deflate'` or `'gzip'`.
1375
1376#### `compressionStream.readable`
1377
1378<!-- YAML
1379added: v17.0.0
1380-->
1381
1382* Type: {ReadableStream}
1383
1384#### `compressionStream.writable`
1385
1386<!-- YAML
1387added: v17.0.0
1388-->
1389
1390* Type: {WritableStream}
1391
1392### Class: `DecompressionStream`
1393
1394<!-- YAML
1395added: v17.0.0
1396changes:
1397  - version: v18.0.0
1398    pr-url: https://github.com/nodejs/node/pull/42225
1399    description: This class is now exposed on the global object.
1400-->
1401
1402#### `new DecompressionStream(format)`
1403
1404<!-- YAML
1405added: v17.0.0
1406-->
1407
1408* `format` {string} One of either `'deflate'` or `'gzip'`.
1409
1410#### `decompressionStream.readable`
1411
1412<!-- YAML
1413added: v17.0.0
1414-->
1415
1416* Type: {ReadableStream}
1417
1418#### `decompressionStream.writable`
1419
1420<!-- YAML
1421added: v17.0.0
1422-->
1423
1424* Type: {WritableStream}
1425
1426### Utility Consumers
1427
1428<!-- YAML
1429added: v16.7.0
1430-->
1431
1432The utility consumer functions provide common options for consuming
1433streams.
1434
1435They are accessed using:
1436
1437```mjs
1438import {
1439  arrayBuffer,
1440  blob,
1441  buffer,
1442  json,
1443  text,
1444} from 'node:stream/consumers';
1445```
1446
1447```cjs
1448const {
1449  arrayBuffer,
1450  blob,
1451  buffer,
1452  json,
1453  text,
1454} = require('node:stream/consumers');
1455```
1456
1457#### `streamConsumers.arrayBuffer(stream)`
1458
1459<!-- YAML
1460added: v16.7.0
1461-->
1462
1463* `stream` {ReadableStream|stream.Readable|AsyncIterator}
1464* Returns: {Promise} Fulfills with an `ArrayBuffer` containing the full
1465  contents of the stream.
1466
1467```mjs
1468import { arrayBuffer } from 'node:stream/consumers';
1469import { Readable } from 'node:stream';
1470import { TextEncoder } from 'node:util';
1471
1472const encoder = new TextEncoder();
1473const dataArray = encoder.encode('hello world from consumers!');
1474
1475const readable = Readable.from(dataArray);
1476const data = await arrayBuffer(readable);
1477console.log(`from readable: ${data.byteLength}`);
1478```
1479
1480```cjs
1481const { arrayBuffer } = require('node:stream/consumers');
1482const { Readable } = require('node:stream');
1483const { TextEncoder } = require('node:util');
1484
1485const encoder = new TextEncoder();
1486const dataArray = encoder.encode('hello world from consumers!');
1487const readable = Readable.from(dataArray);
1488arrayBuffer(readable).then((data) => {
1489  console.log(`from readable: ${data.byteLength}`);
1490});
1491```
1492
1493#### `streamConsumers.blob(stream)`
1494
1495<!-- YAML
1496added: v16.7.0
1497-->
1498
1499* `stream` {ReadableStream|stream.Readable|AsyncIterator}
1500* Returns: {Promise} Fulfills with a {Blob} containing the full contents
1501  of the stream.
1502
1503```mjs
1504import { blob } from 'node:stream/consumers';
1505
1506const dataBlob = new Blob(['hello world from consumers!']);
1507
1508const readable = dataBlob.stream();
1509const data = await blob(readable);
1510console.log(`from readable: ${data.size}`);
1511```
1512
1513```cjs
1514const { blob } = require('node:stream/consumers');
1515
1516const dataBlob = new Blob(['hello world from consumers!']);
1517
1518const readable = dataBlob.stream();
1519blob(readable).then((data) => {
1520  console.log(`from readable: ${data.size}`);
1521});
1522```
1523
1524#### `streamConsumers.buffer(stream)`
1525
1526<!-- YAML
1527added: v16.7.0
1528-->
1529
1530* `stream` {ReadableStream|stream.Readable|AsyncIterator}
1531* Returns: {Promise} Fulfills with a {Buffer} containing the full
1532  contents of the stream.
1533
1534```mjs
1535import { buffer } from 'node:stream/consumers';
1536import { Readable } from 'node:stream';
1537import { Buffer } from 'node:buffer';
1538
1539const dataBuffer = Buffer.from('hello world from consumers!');
1540
1541const readable = Readable.from(dataBuffer);
1542const data = await buffer(readable);
1543console.log(`from readable: ${data.length}`);
1544```
1545
1546```cjs
1547const { buffer } = require('node:stream/consumers');
1548const { Readable } = require('node:stream');
1549const { Buffer } = require('node:buffer');
1550
1551const dataBuffer = Buffer.from('hello world from consumers!');
1552
1553const readable = Readable.from(dataBuffer);
1554buffer(readable).then((data) => {
1555  console.log(`from readable: ${data.length}`);
1556});
1557```
1558
1559#### `streamConsumers.json(stream)`
1560
1561<!-- YAML
1562added: v16.7.0
1563-->
1564
1565* `stream` {ReadableStream|stream.Readable|AsyncIterator}
1566* Returns: {Promise} Fulfills with the contents of the stream parsed as a
1567  UTF-8 encoded string that is then passed through `JSON.parse()`.
1568
1569```mjs
1570import { json } from 'node:stream/consumers';
1571import { Readable } from 'node:stream';
1572
1573const items = Array.from(
1574  {
1575    length: 100,
1576  },
1577  () => ({
1578    message: 'hello world from consumers!',
1579  }),
1580);
1581
1582const readable = Readable.from(JSON.stringify(items));
1583const data = await json(readable);
1584console.log(`from readable: ${data.length}`);
1585```
1586
1587```cjs
1588const { json } = require('node:stream/consumers');
1589const { Readable } = require('node:stream');
1590
1591const items = Array.from(
1592  {
1593    length: 100,
1594  },
1595  () => ({
1596    message: 'hello world from consumers!',
1597  }),
1598);
1599
1600const readable = Readable.from(JSON.stringify(items));
1601json(readable).then((data) => {
1602  console.log(`from readable: ${data.length}`);
1603});
1604```
1605
1606#### `streamConsumers.text(stream)`
1607
1608<!-- YAML
1609added: v16.7.0
1610-->
1611
1612* `stream` {ReadableStream|stream.Readable|AsyncIterator}
1613* Returns: {Promise} Fulfills with the contents of the stream parsed as a
1614  UTF-8 encoded string.
1615
1616```mjs
1617import { text } from 'node:stream/consumers';
1618import { Readable } from 'node:stream';
1619
1620const readable = Readable.from('Hello world from consumers!');
1621const data = await text(readable);
1622console.log(`from readable: ${data.length}`);
1623```
1624
1625```cjs
1626const { text } = require('node:stream/consumers');
1627const { Readable } = require('node:stream');
1628
1629const readable = Readable.from('Hello world from consumers!');
1630text(readable).then((data) => {
1631  console.log(`from readable: ${data.length}`);
1632});
1633```
1634
1635[Streams]: stream.md
1636[WHATWG Streams Standard]: https://streams.spec.whatwg.org/
1637