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