DisposableStack.prototype.adopt()

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

The adopt() method of DisposableStack instances registers a value that doesn't implement the disposable protocol to the stack by providing a custom disposer function.

Syntax

js
adopt(value, onDispose)

Parameters

value

Any value to be registered to the stack.

onDispose

A function that will be called when the stack is disposed. The function receives value as its only argument.

Return value

The same value that was passed in.

Exceptions

TypeError

Thrown if onDispose is not a function.

ReferenceError

Thrown if the stack is already disposed.

Description

The primary purpose of adopt() is to register a value that doesn't implement the disposable protocol to the stack. If the value is already disposable, you can use use() instead, which automatically uses the value's [Symbol.dispose]() method as the disposer.

adopt(value, onDispose) is almost the same as defer(() => onDispose(value)), but it allows you to declare the resource and register it on the same line. This way, there's minimal chance of an error happening between the resource creation and registration, which will cause the resource to leak.

js
using disposer = new DisposableStack();
const reader = disposer.adopt(stream.getReader(), (reader) =>
  reader.releaseLock(),
);
js
using disposer = new DisposableStack();
const reader = stream.getReader();
// If someone adds code in between these lines and an error occurs,
// the stream will be locked forever.
disposer.defer(() => reader.close());

In the same spirit of "make your resource registered as soon as it's declared", you should always wrap your resource acquisition expression in adopt(), instead of extracting it to a separate statement.

js
using disposer = new DisposableStack();
const reader = stream.getReader();
disposer.adopt(reader, (reader) => reader.close());

Examples

Using adopt()

This code consumes a ReadableStream via a ReadableStreamDefaultReader. The reader does not implement the disposable protocol, so we use adopt() to register it to the stack.

js
{
  using disposer = new DisposableStack();
  const reader = disposer.adopt(stream.getReader(), (reader) =>
    reader.releaseLock(),
  );
  const { value, done } = reader.read();
  if (!done) {
    // Process the value
  }
  // The reader.releaseLock() method is called here before exiting
}

Specifications

Specification
ECMAScript Async Explicit Resource Management
# sec-asyncdisposablestack.prototype.adopt

Browser compatibility

desktop mobile server
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Bun
Deno
Node.js
adopt
Chrome – Full support
Chrome 134 (Release date: 2025-03-04)
footnote Full support
Edge – Full support
Edge 134 (Release date: 2025-03-06)
footnote Full support
Firefox – Full support
Firefox 141 (Release date: 2025-07-22)
footnote Full support
Opera – Full support
Opera 119 (Release date: 2025-05-13)
footnote Full support
Safari – No support
Safari
footnote No support
Chrome Android – Full support
Chrome Android 134 (Release date: 2025-03-04)
footnote Full support
Firefox for Android – Full support
Firefox for Android 141 (Release date: 2025-07-22)
footnote Full support
Opera Android – Full support
Opera Android 88 (Release date: 2025-03-19)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Full support
Samsung Internet 29 (Release date: 2025-10-25)
footnote Full support
WebView Android – Full support
WebView Android 134 (Release date: 2025-03-04)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support
Bun – Full support
Bun 1.3 (Release date: 2025-10-10)
footnote Full support
Deno – Full support
Deno 2.2.10 (Release date: 2025-04-15)
footnote Full support
Node.js – Full support
Node.js 24 (Release date: 2025-05-06)
footnote Full support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support

See also