Skip to content

Re-evaluating Node.js Experimental Features #285

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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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