From be1265f55b3db18dc14ac9885a34436562d72f6b Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Tue, 7 Jul 2026 19:39:38 +0200 Subject: [PATCH 1/2] doc: discourage AbortSignal cleanup for long-lived resources Signed-off-by: Efe Karasakal --- doc/api/child_process.md | 16 ++++++++++ doc/api/deprecations.md | 67 ++++++++++++++++++++++++++++++++++++++++ doc/api/net.md | 4 +++ doc/api/stream.md | 4 +++ 4 files changed, 91 insertions(+) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index e90759b16d3fa8..1ec6823edcb8e9 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -242,6 +242,10 @@ can be used to specify the character encoding used to decode the stdout and stderr output. If `encoding` is `'buffer'`, or an unrecognized character encoding, `Buffer` objects will be passed to the callback instead. +> Stability: 0 - Deprecated. Using the `signal` option to destroy long-lived +> child process resources is documentation-only deprecated. See +> [DEP0208](deprecations.md#dep0208-using-abortsignal-to-dispose-of-resources). + ```cjs const { exec } = require('node:child_process'); exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => { @@ -390,6 +394,10 @@ except that it does not spawn a shell by default. Rather, the specified executable `file` is spawned directly as a new process making it slightly more efficient than [`child_process.exec()`][]. +> Stability: 0 - Deprecated. Using the `signal` option to destroy long-lived +> child process resources is documentation-only deprecated. See +> [DEP0208](deprecations.md#dep0208-using-abortsignal-to-dispose-of-resources). + The same options as [`child_process.exec()`][] are supported. Since a shell is not spawned, behaviors such as I/O redirection and file globbing are not supported. @@ -585,6 +593,10 @@ current process. The `shell` option available in [`child_process.spawn()`][] is not supported by `child_process.fork()` and will be ignored if set. +> Stability: 0 - Deprecated. Using the `signal` option to destroy long-lived +> child process resources is documentation-only deprecated. See +> [DEP0208](deprecations.md#dep0208-using-abortsignal-to-dispose-of-resources). + If the `signal` option is enabled, calling `.abort()` on the corresponding `AbortController` is similar to calling `.kill()` on the child process except the error passed to the callback will be an `AbortError`: @@ -735,6 +747,10 @@ process, the default is [`process.env`][]. `undefined` values in `env` will be ignored. +> Stability: 0 - Deprecated. Using the `signal` option to destroy long-lived +> child process resources is documentation-only deprecated. See +> [DEP0208](deprecations.md#dep0208-using-abortsignal-to-dispose-of-resources). + Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code: diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 2109fbe54f93ea..f7981f5c03ed0f 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -4643,6 +4643,73 @@ underlying stream are emitted from `req`. On the write-side you can use `res.writableFinished` to confirm whether the response was written successfully before the response closed. +### DEP0208: Using `AbortSignal` to dispose of resources + + + +Type: Documentation-only + +Using `AbortSignal` to destroy long-lived resources is deprecated. Prefer +`using` for resource cleanup. + +`AbortSignal` is still a good fit for canceling actions, propagating +cancellation from the outside, and timeouts. + +```js +// Deprecated +const ac = new AbortController(); +const server = http.createServer(handler); +server.listen({ port: 3000, signal: ac.signal }); + +await doWork(); +ac.abort(); +``` + +```js +// Use this instead +await using server = http.createServer(handler); +server.listen(3000); + +await doWork(); +``` + +```js +// Deprecated +const ac = new AbortController(); +const stream = addAbortSignal(ac.signal, fs.createReadStream(file)); + +await consume(stream); +ac.abort(); +``` + +```js +// Use this instead +await using stream = fs.createReadStream(file); + +await consume(stream); +``` + +```js +// Deprecated +const ac = new AbortController(); +const child = spawn(command, args, { signal: ac.signal }); + +await doWork(); +ac.abort(); +``` + +```js +// Use this instead +using child = spawn(command, args); + +await doWork(); +``` + [DEP0142]: #dep0142-repl_builtinlibs [DEP0156]: #dep0156-aborted-property-and-abort-aborted-event-in-http [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf diff --git a/doc/api/net.md b/doc/api/net.md index e2f06776409898..b599466aa0747f 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -588,6 +588,10 @@ Otherwise, if `path` is specified, it behaves the same as [`server.listen(path[, backlog][, callback])`][`server.listen(path)`]. If none of them is specified, an error will be thrown. +> Stability: 0 - Deprecated. Using the `signal` option to destroy long-lived +> server resources is documentation-only deprecated. See +> [DEP0208](deprecations.md#dep0208-using-abortsignal-to-dispose-of-resources). + If `exclusive` is `false` (default), then cluster workers will use the same underlying handle, allowing connection handling duties to be shared. When `exclusive` is `true`, the handle is not shared, and attempted port sharing diff --git a/doc/api/stream.md b/doc/api/stream.md index 4af2940a62838a..19c9f9646405f0 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -3555,6 +3555,10 @@ changes: Attaches an AbortSignal to a readable or writeable stream. This lets code control stream destruction using an `AbortController`. +> Stability: 0 - Deprecated. Using [`stream.addAbortSignal()`][] to destroy +> long-lived stream resources is documentation-only deprecated. See +> [DEP0208](deprecations.md#dep0208-using-abortsignal-to-dispose-of-resources). + Calling `abort` on the `AbortController` corresponding to the passed `AbortSignal` will behave the same way as calling `.destroy(new AbortError())` on the stream, and `controller.error(new AbortError())` for webstreams. From d403ca30c41fc897e11cb3e91d402369d0875f7d Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Tue, 7 Jul 2026 19:53:07 +0200 Subject: [PATCH 2/2] doc: wrap in async fns to please the linter Signed-off-by: Efe Karasakal --- doc/api/deprecations.md | 52 +++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index f7981f5c03ed0f..d82e7e75be4b6d 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -4662,52 +4662,64 @@ cancellation from the outside, and timeouts. ```js // Deprecated -const ac = new AbortController(); -const server = http.createServer(handler); -server.listen({ port: 3000, signal: ac.signal }); +async function example() { + const ac = new AbortController(); + const server = http.createServer(handler); + server.listen({ port: 3000, signal: ac.signal }); -await doWork(); -ac.abort(); + await doWork(); + ac.abort(); +} ``` ```js // Use this instead -await using server = http.createServer(handler); -server.listen(3000); +async function example() { + await using server = http.createServer(handler); + server.listen(3000); -await doWork(); + await doWork(); +} ``` ```js // Deprecated -const ac = new AbortController(); -const stream = addAbortSignal(ac.signal, fs.createReadStream(file)); +async function example() { + const ac = new AbortController(); + const stream = addAbortSignal(ac.signal, fs.createReadStream(file)); -await consume(stream); -ac.abort(); + await consume(stream); + ac.abort(); +} ``` ```js // Use this instead -await using stream = fs.createReadStream(file); +async function example() { + await using stream = fs.createReadStream(file); -await consume(stream); + await consume(stream); +} ``` ```js // Deprecated -const ac = new AbortController(); -const child = spawn(command, args, { signal: ac.signal }); +async function example() { + const ac = new AbortController(); + const child = spawn(command, args, { signal: ac.signal }); -await doWork(); -ac.abort(); + await doWork(); + ac.abort(); +} ``` ```js // Use this instead -using child = spawn(command, args); +async function example() { + using child = spawn(command, args); -await doWork(); + await doWork(); +} ``` [DEP0142]: #dep0142-repl_builtinlibs