Skip to content

Re-evaluating Node.js Experimental Features #285

@RafaelGSS

Description

@RafaelGSS

I believe it's time to discuss our policies around experimental features in the project. Features like --experimental-network-import are challenging to assess and maintain, especially when there is no active champion or creator overseeing them.

Proposal

I propose that when the creator or champion of an experimental feature becomes inactive, we should:

  1. Re-evaluate the benefits of the feature.
  2. Decide whether to remove the feature entirely or delegate its maintenance to a team.

This approach will help us set clear expectations, assess and review vulnerabilities, and ensure better maintenance of our experimental features.

Recent Example

We recently dropped the --experimental-policy feature because:

  • We were receiving reports about it.
  • The documentation did not clearly define its boundaries and security expectations, making it difficult to assess.

Actionable Steps

To facilitate this discussion, I have written a simple script to list all experimental APIs from nodejs/node/docs/api/**. You can find it here.

Can we evaluate these experimental features either asynchronously or through a dedicated call?

File API Group Header Re-Evaluated
doc/api/async_context.md AsyncLocalStorage.bind(fn) AsyncLocalStorage
doc/api/async_context.md AsyncLocalStorage.snapshot() AsyncLocalStorage
doc/api/async_context.md asyncLocalStorage.disable() AsyncLocalStorage
doc/api/async_context.md asyncLocalStorage.enterWith(store) AsyncLocalStorage
doc/api/async_context.md asyncLocalStorage.exit(callback[, ...args]) AsyncLocalStorage
doc/api/async_hooks.md AsyncHooks Async hooks
doc/api/buffer.md buffer.resolveObjectURL(id) Buffer
doc/api/child_process.md subprocess[Symbol.dispose]() Child Process
doc/api/cli.md --allow-addons Permission Model
doc/api/cli.md --allow-child-process Permission Model
doc/api/cli.md --allow-fs-read Permission Model
doc/api/cli.md --allow-fs-write Permission Model
doc/api/cli.md --allow-wasi Permission Model
doc/api/cli.md --allow-worker Permission Model
doc/api/cli.md --build-snapshot Startup Snapshot
doc/api/cli.md --build-snapshot-config Startup Snapshot
doc/api/cli.md -C condition, --conditions=condition Conditional Exports
doc/api/cli.md --cpu-prof
doc/api/cli.md --cpu-prof-dir
doc/api/cli.md --cpu-prof-interval
doc/api/cli.md --cpu-prof-name
doc/api/cli.md --disable-warning=code-or-type
doc/api/cli.md --expose-gc
doc/api/cli.md --env-file=config Node Env
doc/api/cli.md --experimental-default-type=type Loaders
doc/api/cli.md --experimental-detect-module Loaders
doc/api/cli.md --experimental-network-imports Loaders
doc/api/cli.md --experimental-permission Permission Model
doc/api/cli.md --experimental-require-module Loaders
doc/api/cli.md --experimental-sea-config SEA
doc/api/cli.md --experimental-shadow-realm
doc/api/cli.md --experimental-test-module-mocks Test Runner
doc/api/cli.md --experimental-test-snapshots Test Runner
doc/api/cli.md --frozen-intrinsics
doc/api/cli.md --heap-prof
doc/api/cli.md --heap-prof-dir
doc/api/cli.md --heap-prof-interval
doc/api/cli.md --heap-prof-name
doc/api/cli.md --heapsnapshot-near-heap-limit=max_count
doc/api/cli.md --import=module Loaders
doc/api/cli.md --jitless
doc/api/cli.md --no-experimental-global-navigator
doc/api/cli.md --run
doc/api/cli.md --snapshot-blob=path Startup Snapshot
doc/api/cli.md --test-update-snapshots
doc/api/cli.md NODE_COMPILE_CACHE=dir
doc/api/cli.md Source map cache
doc/api/corepack.md Corepack Corepack
doc/api/crypto.md crypto.hash(algorithm, data[, outputEncoding]) Crypto
doc/api/dgram.md socket[Symbol.asyncDispose]()
doc/api/diagnostics_channel.md diagnostics_channel.tracingChannel(nameOrChannels) Diagnostics
doc/api/diagnostics_channel.md channel.bindStore(store[, transform]) Diagnostics
doc/api/diagnostics_channel.md channel.unbindStore(store) Diagnostics
doc/api/diagnostics_channel.md channel.runStores(context, fn[, thisArg[, ...args]]) Diagnostics
doc/api/diagnostics_channel.md Class: TracingChannel Diagnostics
doc/api/diagnostics_channel.md tracingChannel.subscribe(subscribers) Diagnostics
doc/api/diagnostics_channel.md tracingChannel.unsubscribe(subscribers) Diagnostics
doc/api/diagnostics_channel.md tracingChannel.traceSync(fn[, context[, thisArg[, ...args]]]) Diagnostics
doc/api/diagnostics_channel.md tracingChannel.tracePromise(fn[, context[, thisArg[, ...args]]]) Diagnostics
doc/api/diagnostics_channel.md tracingChannel.traceCallback(fn, position, context, thisArg, ...args) Diagnostics
doc/api/diagnostics_channel.md Built-in Channels
doc/api/errors.md ERR_INPUT_TYPE_NOT_ALLOWED
doc/api/errors.md ERR_REQUIRE_CYCLE_MODULE
doc/api/errors.md ERR_REQUIRE_ASYNC_MODULE
doc/api/errors.md ERR_REQUIRE_ESM
doc/api/errors.md ERR_UNKNOWN_FILE_EXTENSION
doc/api/errors.md ERR_UNKNOWN_MODULE_FORMAT
doc/api/errors.md ERR_USE_AFTER_CLOSE
doc/api/errors.md ERR_NETWORK_IMPORT_BAD_RESPONSE
doc/api/errors.md ERR_NETWORK_IMPORT_DISALLOWED
doc/api/esm.md import.meta.dirname
doc/api/esm.md import.meta.filename
doc/api/esm.md import.meta.resolve(specifier)
doc/api/esm.md JSON modules ESM
doc/api/esm.md Wasm modules ESM
doc/api/esm.md HTTPS and HTTP imports ESM
doc/api/events.md events.addAbortListener(signal, listener) Events
doc/api/fs.md filehandle.readableWebStream([options]) File System
doc/api/fs.md filehandle[Symbol.asyncDispose]() File System
doc/api/fs.md fsPromises.glob(pattern[, options]) File System
doc/api/fs.md fs.glob(pattern[, options], callback) File System
doc/api/fs.md fs.openAsBlob(path[, options]) File System
doc/api/fs.md fs.globSync(pattern[, options]) File System
doc/api/fs.md dirent.parentPath File System
doc/api/globals.md Class: ByteLengthQueuingStrategy
doc/api/globals.md Class: CompressionStream
doc/api/globals.md Class: CountQueuingStrategy
doc/api/globals.md Crypto Crypto
doc/api/globals.md CryptoKey Crypto
doc/api/globals.md CustomEvent
doc/api/globals.md Class: DecompressionStream
doc/api/globals.md Navigator
doc/api/globals.md Class: ReadableByteStreamController
doc/api/globals.md Class: ReadableStream
doc/api/globals.md Class: ReadableStreamBYOBReader
doc/api/globals.md Class: ReadableStreamBYOBRequest
doc/api/globals.md Class: ReadableStreamDefaultController
doc/api/globals.md Class: ReadableStreamDefaultReader
doc/api/globals.md SubtleCrypto
doc/api/globals.md Class: TextDecoderStream
doc/api/globals.md Class: TextEncoderStream
doc/api/globals.md TransformStream TransformStream
doc/api/globals.md TransformStreamDefaultController TransformStreamDefaultController
doc/api/globals.md WebSocket globals.md
doc/api/globals.md WritableStream WritableStream
doc/api/globals.md WritableStreamDefaultController WritableStreamDefaultController
doc/api/globals.md WritableStreamDefaultWriter WritableStreamDefaultWriter
doc/api/http.md serverSymbol.asyncDispose http.md
doc/api/http2.md serverSymbol.asyncDispose http2.md
doc/api/https.md serverSymbol.asyncDispose https.md
doc/api/inspector.md Promises API inspector.md
doc/api/module.md module.register(specifier[, parentURL][, options]) module.md
doc/api/module.md Customization Hooks module.md
doc/api/module.md initialize() module.md
doc/api/module.md resolve(specifier, context, nextResolve) module.md
doc/api/module.md load(url, context, nextLoad) module.md
doc/api/module.md Source map v3 support module.md
doc/api/n-api.md node_api_nogc_env n-api.md
doc/api/n-api.md node_api_nogc_finalize n-api.md
doc/api/n-api.md node_api_create_external_string_latin1 n-api.md
doc/api/n-api.md node_api_create_external_string_utf16 n-api.md
doc/api/n-api.md node_api_create_property_key_utf16 n-api.md
doc/api/n-api.md node_api_post_finalizer n-api.md
doc/api/net.md serverSymbol.asyncDispose net.md
doc/api/packages.md Determining package manager packages.md
doc/api/packages.md "packageManager" packages.md
doc/api/process.md process.constrainedMemory() process.md
doc/api/process.md process.availableMemory() process.md
doc/api/process.md process.getActiveResourcesInfo() process.md
doc/api/process.md process.loadEnvFile(path) process.md
doc/api/process.md process.setSourceMapsEnabled(val) process.md
doc/api/process.md process.sourceMapsEnabled process.md
doc/api/readline.md Promises API readline.md
doc/api/single-executable-applications.md Single executable applications single-executable-applications.md
doc/api/stream.md writable.writableAborted stream.md
doc/api/stream.md readable.readableAborted stream.md
doc/api/stream.md readable.readableDidRead stream.md
doc/api/stream.md readableSymbol.asyncDispose stream.md
doc/api/stream.md readable.compose(stream[, options]) stream.md
doc/api/stream.md readable.iterator([options]) stream.md
doc/api/stream.md readable.map(fn[, options]) stream.md
doc/api/stream.md readable.filter(fn[, options]) stream.md
doc/api/stream.md readable.forEach(fn[, options]) stream.md
doc/api/stream.md readable.toArray([options]) stream.md
doc/api/stream.md readable.some(fn[, options]) stream.md
doc/api/stream.md readable.find(fn[, options]) stream.md
doc/api/stream.md readable.every(fn[, options]) stream.md
doc/api/stream.md readable.flatMap(fn[, options]) stream.md
doc/api/stream.md readable.drop(limit[, options]) stream.md
doc/api/stream.md readable.take(limit[, options]) stream.md
doc/api/stream.md readable.reduce(fn[, initial[, options]]) stream.md
doc/api/stream.md stream.compose(...streams) stream.md
doc/api/stream.md stream.Readable.fromWeb(readableStream[, options]) stream.md
doc/api/stream.md stream.Readable.isDisturbed(stream) stream.md
doc/api/stream.md stream.isErrored(stream) stream.md
doc/api/stream.md stream.isReadable(stream) stream.md
doc/api/stream.md stream.Readable.toWeb(streamReadable[, options]) stream.md
doc/api/stream.md stream.Writable.fromWeb(writableStream[, options]) stream.md
doc/api/stream.md stream.Writable.toWeb(streamWritable) stream.md
doc/api/stream.md stream.Duplex.fromWeb(pair[, options]) stream.md
doc/api/stream.md stream.Duplex.toWeb(streamDuplex) stream.md
doc/api/test.md Watch mode test.md
doc/api/test.md Collecting code coverage test.md
doc/api/test.md Snapshot testing test.md
doc/api/test.md snapshot test.md
doc/api/test.md snapshot.setDefaultSnapshotSerializers(serializers) test.md
doc/api/test.md snapshot.setResolveSnapshotPath(fn) test.md
doc/api/test.md MockModuleContext test.md
doc/api/test.md mock.module(specifier[, options]) test.md
doc/api/test.md MockTimers test.md
doc/api/test.md context.assert.snapshot(value[, options]) test.md
doc/api/test.md context.plan(count) test.md
doc/api/timers.md immediateSymbol.dispose timers.md
doc/api/timers.md timeoutSymbol.dispose timers.md
doc/api/timers.md timersPromises.scheduler.wait(delay[, options]) timers.md
doc/api/timers.md timersPromises.scheduler.yield() timers.md
doc/api/tracing.md Trace events tracing.md
doc/api/url.md URL.createObjectURL(blob) url.md
doc/api/url.md URL.revokeObjectURL(id) url.md
doc/api/util.md util.MIMEType util.MIMEType
doc/api/util.md util.parseEnv(content) util.md
doc/api/util.md util.styleText(format, text) util.md
doc/api/util.md util.transferableAbortController() util.md
doc/api/util.md util.transferableAbortSignal(signal) util.md
doc/api/util.md util.aborted(signal, resource) util.md
doc/api/v8.md v8.queryObjects(ctor[, options]) v8.md
doc/api/v8.md v8.setHeapSnapshotNearHeapLimit(limit) v8.md
doc/api/v8.md Startup Snapshot API v8.md
doc/api/vm.md vm.Module vm.Module
doc/api/vm.md vm.SourceTextModule vm.SourceTextModule
doc/api/vm.md vm.SyntheticModule vm.SyntheticModule
doc/api/vm.md vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER vm.md
doc/api/vm.md vm.measureMemory([options]) vm.md
doc/api/wasi.md WebAssembly System Interface (WASI) wasi.md
doc/api/webcrypto.md Ed25519/Ed448/X25519/X448 key pairs webcrypto.md
doc/api/worker_threads.md port.hasRef() worker_threads.md

(Feel free to edit this table)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions