The ReadableStreamBYOBReader interface of the Streams API defines a reader for a ReadableStream that supports zero-copy reading from an underlying byte source. It is used for efficient copying from underlying sources where the data is delivered as an "anonymous" sequence of bytes, such as files.

An instance of this reader type should usually be obtained by calling ReadableStream.getReader() on the stream, specifying mode: "byob" in the options parameter. The readable stream must have an underlying byte source. In other words, it must have been constructed specifying an underlying source with type: "bytes").

Using this kind of reader, a read() request when the readable stream's internal queues are empty will result in a zero copy transfer from the underlying source (bypassing the stream's internal queues). If the internal queues are not empty, a read() will satisfy the request from the buffered data.

Note that the methods and properties are similar to those for the default reader (ReadableStreamDefaultReader). The read() method differs in that it provide a view into which data should be written.



Creates and returns a ReadableStreamBYOBReader object instance.


ReadableStreamBYOBReader.closed Read only

Returns a Promise that fulfills when the stream closes, or rejects if the stream throws an error or the reader's lock is released. This property enables you to write code that responds to an end to the streaming process.



Returns a Promise that resolves when the stream is canceled. Calling this method signals a loss of interest in the stream by a consumer. The supplied reason argument will be given to the underlying source, which may or may not use it.

Passes a view into which data must be written, and returns a Promise that resolves with the next chunk in the stream or rejects with an indication that the stream is closed or has errored.


Releases the reader's lock on the stream.


The example below is taken from the live examples in Using readable byte streams.

First create the reader using ReadableStream.getReader() on the stream, specifying mode: "byob" in the options parameter. As this is a "Bring Your Own Buffer" reader, we also need to create an ArrayBuffer to read into.

const reader = stream.getReader({ mode: "byob" });
let buffer = new ArrayBuffer(4000);

A function that uses the reader is shown below. This calls the read() method recursively to read data into the buffer. The method takes a Uint8Array typed array which is a view over the part of the original array buffer that has not yet been written. The parameters of the view are calculated from the data that was received in previous calls, which define an offset into the original array buffer.


function readStream(reader) {
  let bytesReceived = 0;
  let offset = 0;

  while (offset < buffer.byteLength) {
    // read() returns a promise that resolves when a value has been received Uint8Array(buffer, offset, buffer.byteLength - offset))
      .then(function processBytes({ done, value }) {
        // Result objects contain two properties:
        // done  - true if the stream has already given all its data.
        // value - some data. Always undefined when done is true.

        if (done) {
          // There is no more data in the stream

        buffer = value.buffer;
        offset += value.byteLength;
        bytesReceived += value.byteLength;

        // Read some more, and call this function again
        return Uint8Array(buffer, offset, buffer.byteLength - offset)).then(processBytes);

When there is no more data in the stream, the read() method resolves with an object with the property done set to true, and the function returns.

The ReadableStreamBYOBReader.closed property returns a promise that can be used to monitor for the stream being closed or errored, or the reader lock being released.

  .then(() => { /* Resolved - code to handle stream closing */ } )
  .catch(() => { /* Rejected - code to handle error */ } );

To cancel the stream call ReadableStreamBYOBReader.cancel(), optionally specifying a reason. This returns a promise that will resolve when the stream has been cancelled. When the stream is cancelled the controller will in turn call cancel() on the underlying source, passing in the optional reason.

The example code in Using readable byte streams calls the cancel method when a button is pressed, as shown:

button.addEventListener('click', () => {
  reader.cancel("user choice").then(() => console.log('cancel complete'));

The consumer can also call releaseLock() to release the reader's hold on the stream, but only when no read is pending:



Streams Standard
# byob-reader-class

Browser compatibility

BCD tables only load in the browser

See also