507 Commits
Author SHA1 Message Date
Matteo Collina 9a9f7e87b8 process: return unregister fn from finalization
process.finalization.register() and registerBeforeExit() now return
a function that removes only that registration, leaving other
registrations for the same object in place. The function does not
hold a strong reference to the object.

Each registration now uses its WeakRef as the unregister token, which
also makes process.finalization.unregister() remove the entries from
the FinalizationRegistry; previously it passed the object as the
token, which was never registered, so the call had no effect.

Refs: https://github.com/nodejs/node/pull/66482

Signed-off-by: Matteo Collina <matteo.collina@gmail.com>
Assisted-by: pi
PR-URL: https://github.com/nodejs/node/pull/66482
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
2026-10-18 06:36:43 +00:00
Matteo Collina 4e09bf3fb2 process: mark process.finalization as release candidate
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/66436
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-10-10 11:57:54 +02:00
Rafael Gonzaga ff31c97032 lib: add --allow-fs-vfs to permission available flags
Without it, --allow-fs-vfs was accepted without --permission and was not
propagated to child processes like the other --allow-* flags.

Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs/node/pull/66554
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
2026-10-10 08:29:51 +00:00
Marco Ippolito 3c577146aa src: mark config file as stable
Signed-off-by: Marco Ippolito <marcoippolito54@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66431
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
2026-10-05 16:47:38 +00:00
Jungwon Sohn 4791219541 module: centralize builtin exposure policies
Keep scheme-only and option-gated builtin exposure rules in the
JavaScript loader. Leave option registration and code-cache
categorization with their native owners.

Assisted-by: Codex
Signed-off-by: sjungwon03 <sjungwon03@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66292
Refs: https://github.com/nodejs/node/pull/65418
Refs: https://github.com/nodejs/node/pull/65964
Refs: https://github.com/nodejs/node/pull/65920
Refs: https://github.com/nodejs/node/pull/65840
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
2026-10-02 17:29:27 +00:00
Matteo Collina 4486dce709 process: use a class for nextTick resources
The resource created for each `process.nextTick()` call was an object
literal with three computed symbol keys. V8 builds such literals from a
boilerplate that only covers the static keys, so the symbol-keyed
properties end up in a separate property array allocated per tick, and
each computed-key store goes through the runtime.

Construct the resource through a class instead, so that every tick
object shares one map with all five fields in-object.

process/next-tick-breadth-args.js: ~1.58M -> ~1.95M ops/s (+23%).

Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/66415
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2026-10-02 14:45:34 +00:00
James M Snell f378cfcfbf src,lib: add --allow-env permission
Necessarily semver-major.

When `--permission` is on, every env var not matched by
`--allow-env` is removed at startup. It takes names,
prefix patterns (`PREFIX_*`), or `*`, repeatable or
comma-sep'd.

There are a range of env vars that Node.js itself uses,
and a default range that are generally known to be safe
in common usage. These are never scrubbed. These include
things like `NODE_OPTIONS`, `NODE_EXTRA_CA_CERTS`, `PATH`,
`HOME`, etc. `NODE_ENV` is not in the defaults and must
be allowed explicitly.

Proxy vars (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) are
also not in the defaults since they can carry credentials.
When `--use-env-proxy` or `NODE_USE_ENV_PROXY` is set and
any of them were removed, a single warning naming them is
emitted.

Env vars can be dropped at runtime after reading using
`permission.drop()`. This is a stronger protection than
using `process.env.FOO = undefined` because it will
scrub the env var also from the environment block.

On Linux, the removed entries are overwritten in the
initial environment block. fs reads of any other
process's /proc/<pid>/environ, ancestors included, are
denied regardless of `--allow-fs-read`. A process's own
is readable only with `--allow-env=*`. Symlinks are
resolved before the check so paths like
/dev/fd/../../<ppid>/environ are caught. The check only
canonicalizes paths that statfs() reports are on procfs.

On Windows, removal also clears the C runtime's copy
of the environ using _wputenv_s.

Reading a removed name returns undefined, warns once per
name, and publishes to a diagnostics channel.

Env file keys are allowed. If the user had reason to pass
in an env file the assumption is they meant to allow them.

File-source config (node.config.json and NODE_OPTIONS
from a .env file) can only narrow the allow list.

Embedders must call ScrubProcessEnvironment() themselves
on startup. This is left up to the embedder to determine
the exact timing but needs to be called before startup
actually happens.

Child processes are started with `--allow-env=*`. Those
either receive the explicit env they were started with
or only the env they inherit from the parent. Since the
parent process is scrubbed, and the child cannot read
any other process's /proc/<pid>/environ, it should never
see more than the parent can.

Main part of the impl was done by hand. Docs, tests,
verification pass, and cleanup nits were automated.

Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode
PR-URL: https://github.com/nodejs/node/pull/66132
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-09-26 21:18:43 +00:00
Philipp Dunkel 28994575bc vfs: drop --vfs-mount, pin the load mount point
--vfs-mount mounted a source without running it, and shared one ordered
list of sources with --vfs-load, so neither option could say which entry
it had contributed: the entry point was recovered from the position of
--vfs-load among the mounts, in a list NODE_OPTIONS could prepend to.
Nothing needs more than one mount from the command line: a program that
wants more can mount them itself through node:vfs, where it also gets
the instance.

Remove --vfs-mount, leaving --vfs-load with the single source it mounts
and runs, and reserve layer 0 for that source, numbering the file
systems a program mounts itself from 1. The source is then at the same
mount point in every thread, whatever else that thread mounts -
including a thread where a --require preload mounted a file system of
its own first - so a path into it stays valid in a worker.

A worker still does not run that entry point: it inherits the source but
not the decision to load from it. A worker created with its own execArgv
inherits neither, so the documentation now says that such a worker must
be given --experimental-vfs and --vfs-load again to run a script from
the mount, and that --experimental-vfs is also what makes node:vfs
available to the worker's own code.

ERR_VFS_INVALID_TARGET now names --vfs-load as the source's origin, and
the startup test moves to test-vfs-load.js, with the cases that covered
mounting without loading removed and cases for the reserved mount point
added.

Signed-off-by: Philipp Dunkel <pip@pipobscure.com>
PR-URL: https://github.com/nodejs/node/pull/66162
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-09-23 14:45:25 +00:00
Philipp Dunkel 6a7f94c9bf vfs: add --vfs-mount and --vfs-load startup flags
Mounting a virtual file system requires calling vfs.mount() from inside
the program, so a program cannot itself be served from one: something
already running has to mount the VFS first.

Add two startup flags. --vfs-mount=<source> mounts a directory or an
archive as a virtual file system, and may be repeated.
--vfs-load=<source> mounts that source the same way and additionally
runs the entry point and all subsequent require()/import resolution
against it rather than against the real file system, so an application
can be run straight out of a directory or a ZIP archive:

  node --experimental-vfs --vfs-load=my-app.zip

Both options append to one list, so mounts happen in the order written:

  node --experimental-vfs --vfs-mount=a --vfs-load=b --vfs-mount=c

mounts a, b and c in that order and runs b. Mounting the same source
twice mounts it twice, at two mount points, and the entry point comes
from the mount --vfs-load contributed rather than the earlier one.

The provider backing a source is chosen from the source itself rather
than from its name: a directory is served by RealFSProvider and a file
whose bytes are a ZIP archive by ZipProvider, so an archive can carry
any extension. vfs.registerProvider() registers a provider for formats
there is no built-in for; selection is deferred until -r and --import
preloads have run, so a preloaded module can register one before its
source is claimed.

The entry point comes from the mount the way `node <directory>` takes
one, from package.json "main" or index.js. Nothing is consumed as an
entry point argument, so every positional reaches the program unchanged
from argv[2] on, and argv[1] reports the named source rather than the
reserved mount point, which is an opaque implementation detail.

--vfs-load may be given at most once, and is not permitted in
NODE_OPTIONS: which entry point runs is the command line's decision, and
NODE_OPTIONS is parsed first, so an environment variable could otherwise
redirect any invocation. --vfs-mount is permitted there. Workers inherit
the same mounts in the same order but not the loading: a worker mounts
what the parent mounted and runs its own entry point.

Signed-off-by: Philipp Dunkel <pip@pipobscure.com>
PR-URL: https://github.com/nodejs/node/pull/65748
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-09-17 20:38:00 +00:00
James M Snell dff7a160fe lib: put node:bench behind an --experimental-bench flag
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode
PR-URL: https://github.com/nodejs/node/pull/65920
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Xuguang Mei <meixuguang@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
2026-09-12 08:29:12 +00:00
Shelley Vohr ddc0a0aa28 worker: start worker threads from the built-in snapshot
Every `new Worker()` runs the whole internal bootstrap (realm, node, web
exposure, thread and process-state switches) in its fresh isolate,
compiling ~80 builtins with the code cache; only the main thread
deserializes its principal context from the built-in snapshot. That
bootstrap is about half of a worker's cold start.

The bootstrapped principal context in the snapshot is nearly
thread-neutral: the worker-side switch scripts (is_not_main_thread,
does_not_own_process_state) are written as overrides of the main-thread
ones, and the per-thread values of the `worker` binding were the only
thread-specific data baked into the context. Let a worker deserialize
that same context and EnvSerializeInfo and apply the two worker-side
switches on top:

- worker binding: threadId, threadName, isMainThread, isInternalThread,
  ownsProcessState and resourceLimits become lazy properties of the
  per-isolate template, computed from the Environment on first read.
- CreateEnvironment(): when a worker (its IsolateData has a Worker)
  passes an empty context, deserialize kNodeMainContextIndex and run
  internal/bootstrap/switches/is_not_main_thread and, unless the worker
  owns process state, does_not_own_process_state after
  InitializeMainContext().
- Worker::Run(): take that path when the embedded built-in snapshot is
  in use (not an embedder's or a --snapshot-blob one, which has run
  application code), browser globals are not disabled and
  --no-worker-snapshot was not given; otherwise bootstrap as before.
- is_not_main_thread.js: also delete _debugPause and the profiler idle
  notifier helpers that is_main_thread.js installs.
- pre_execution: run the snapshot's deserialize callbacks (Buffer pool,
  default resolver, cached cwd) on worker threads too, now that a worker
  can come from a snapshot.
- --[no-]worker-snapshot per-isolate option, documented.

Sequential new Worker() -> 'online' -> terminate goes from ~20.9 ms to
~10.3 ms per worker on x64 Linux; --no-worker-snapshot restores the old
number.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65336
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2026-09-04 13:28:27 +00:00
Filip Skokan 1309975c65 crypto: add strict mode to --force-fips
Allow --force-fips to take an optional provider or strict mode. Keep
provider as the current default and explicit compatibility mode.

In strict mode, return failure from the OpenSSL 3.4+ FIPS indicator
callback when it reports a non-approved operation. Install the callback
for enforcement without implicitly enabling diagnostics;
--enable-fips-indicator-events remains the independent observation
opt-in.

Keep the bare form mapped to provider for compatibility, allowing the
default to change to strict in a future major release. Preserve the mode
when forwarding flags to child test processes, and keep the parser's
internal mode storage out of process.allowedNodeEnvironmentFlags.

Document the callback scope limitations and cover provider
compatibility, validation, synchronous crypto, WebCrypto, Workers, and
opt-in event publication.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65645
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2026-09-02 08:50:36 +00:00
Filip Skokan d5d203a269 crypto: add FIPS indicator diagnostics channel
OpenSSL 3.4 added an indicator callback for operations that its FIPS
provider allows after an approved-mode check has been relaxed.

Publish these indicators on the crypto.fips.indicator diagnostics
channel when Node.js is started with --enable-fips-indicator-events.
Leave the OpenSSL callback unset otherwise so ordinary cryptographic
operations have no indicator callback overhead.

Keep the channel observation-only so enforcement remains the
responsibility of the provider configuration, and independent diagnostic
subscribers can coexist.

Install the native callback during process initialization so it is not
changed while Workers or thread-pool jobs can be using OpenSSL. Preserve
callbacks installed by embedders, and queue bounded, coalesced messages
for asynchronous delivery on the main environment.

Document the channel as best-effort telemetry that cannot identify the
originating call or establish FIPS validation.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65645
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2026-09-02 08:50:34 +00:00
Seungmin Nam c4336d90c0 permission: support URL and Uint8Array as has()/drop() reference
normalizeReference() adds URL and Uint8Array support to has()/drop();
the existing string/Buffer behavior is unchanged. BufferValue replaces
Utf8Value so a Buffer/TypedArray reference is copied as raw bytes
instead of a lossy UTF-8 conversion.

Signed-off-by: seungmin Nam <nhjbest22@g.skku.edu>
PR-URL: https://github.com/nodejs/node/pull/65492
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-31 14:59:47 +00:00
Antoine du Hamel 057e591f7c lib,src: remove --no-experimental-websocket CLI flag
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65284
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
2026-08-23 21:16:19 +00:00
Shelley Vohr e38eede0e5 lib: load fewer builtins when bootstrapping without a snapshot
Contexts that are not deserialized from the built-in snapshot -- worker
threads, and the main context of embedders that create their own
isolate or of `node --no-node-snapshot` -- compile (with the code cache
at best) every builtin the bootstrap touches, so each eagerly required
builtin is startup time (~0.15-0.4 ms apiece). A number of them are only
required eagerly so that they end up in the snapshot, or for features
the bootstrap path never uses.

Load lazily what those paths do not need:

- is_main_thread.js: preload util, url, the ESM loader (translators,
  resolver, module_job/map, source maps, node:module, vm modules, mime,
  data_url, the TypeScript stripper), internal/blob and
  internal/dns/utils only while building a snapshot; they load on first
  use otherwise.
- fs: internal/blob (+ internal/encoding and its tables) is only used
  by fs.openAsBlob().
- internal/url: internal/data_url (+ internal/mime) is only used by the
  Buffer-returning file URL helpers.
- internal/process/execution, the CommonJS loader, esm/translators and
  esm/load: the TypeScript stripper and data: URL helpers are only
  needed for TypeScript sources / data: URLs.
- pre_execution: internal/dns/utils (+ internal/net) is only needed up
  front to validate an explicit --dns-result-order or to register the
  resolver's snapshot serializer; the default order becomes the
  variable's initializer.
- internal/worker: event_loop_utilization and error_serdes are only
  needed once a sub-worker's ELU is read or it reports an error.
- worker_threads: `locks` is defined lazily, like util's lazy exports.

Main-thread startup with the snapshot is unchanged (the same modules
are preloaded into it; the bootstrap-modules test lists are adjusted).
A bare worker compiles 95 -> 83 builtins (cold start -5%); without the
snapshot an empty CommonJS entry point compiles 76 -> 59 builtins and an
empty ES module entry point 76 -> 69.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65329
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
2026-08-22 17:07:39 +00:00
Aviv Keller c73d0b1c5b worker: add wpt tests for Web Workers
Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: https://github.com/nodejs/node/pull/64894
Fixes: https://github.com/nodejs/node/issues/43583
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-08-15 13:15:51 -07:00
Aviv Keller b9afdd0b87 worker: add support for Web Workers
Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: https://github.com/nodejs/node/pull/64894
Fixes: https://github.com/nodejs/node/issues/43583
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-08-15 13:15:47 -07:00
Filip Skokan 565c3daebf crypto: support loading private keys through STORE loaders
Accept WHATWG URL objects in private-key inputs and load referenced keys
through OpenSSL STORE loaders. Pass optional property queries and
passphrases while preserving provider-owned EVP_PKEY objects for
ordinary KeyObject and CryptoKey operations.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/63949
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-08-02 20:18:09 +00:00
David Evans d1f3d0abb5 permission: add unique warning codes
Adds unique warning codes of the form PERM0000 for all permissions
related SecurityWarnings, so that they can be individually silenced
if required.

Fixes: https://github.com/nodejs/node/issues/59818
Signed-off-by: David Evans <davidje13@users.noreply.github.com>
PR-URL: https://github.com/nodejs/node/pull/64414
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-02 13:54:33 +00:00
RafaelGSS b413a9afec permission: check final report output path
Refs: https://hackerone.com/reports/3815767
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs-private/node-private/pull/908
CVE-ID: CVE-2026-58039
2026-07-29 10:41:17 -03:00
Stephen Belanger 594d0c562c diagnostics_channel: grow native channel storage
Every string-named JavaScript channel consumed an entry in the fixed
native subscriber array. Creating more than 1,024 channels triggered a
CHECK and terminated the process.

Allocate slots only for native publishers and grow the aliased buffer
when it fills. Refresh the JavaScript view after resizing and preserve
the capacity in snapshots.

Signed-off-by: Stephen Belanger <admin@stephenbelanger.com>
PR-URL: https://github.com/nodejs/node/pull/64497
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-07-22 03:40:02 +00:00
Trivikram Kamat 75aec8ecf8 process: fix finalization cleanup ref tracking
Use SafeSet collections for finalization refs so insertion, removal,
and emptiness checks match the identity-based tracking model.

This also fixes cleanup removal for collected refs. Previously cleanup
used the ref index as the splice delete count, which could remove later
live refs when the collected ref was not first.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: https://github.com/nodejs/node/pull/64087
Fixes: https://github.com/nodejs/node/issues/64086
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
2026-06-30 21:38:02 +00:00
RafaelGSS 9cc79c177d permission: handle process.chdir on writereport
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs-private/node-private/pull/870
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
CVE-ID: CVE-2026-48617
Refs: https://hackerone.com/reports/3625987
2026-06-18 06:29:23 +02:00
Rafael Gonzaga 956e2a2b86 lib,permission: add permission.drop
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs/node/pull/62672
Refs: https://github.com/nodejs/node/issues/62223
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-05-26 13:40:14 +00:00
Matteo Collina c9562ddb82 vfs: add minimal node:vfs subsystem
Adds the node:vfs builtin module with VirtualFileSystem and
provider classes. No integration with fs, modules, or SEA.

Assisted-by: Claude-Opus4.7
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/63115
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2026-05-23 18:43:31 +00:00
James M Snell 436748fc28 src,lib: implement experimental DTLS API
Decided to take a short break from the work on QUIC
to implement a DTLS API. Very experimental at this
point but the basic API is there (inspired by the
QUIC API work).

The implementation is based on OpenSSL's built-in
DTLS support and no other dependencies are required.

DTLS is a datagram-based version of TLS that is used
for things like WebRTC and CoAP. It provides similar
security guarantees as TLS but is designed to work over
UDP instead of TCP.

This shouldn't be considered ready for production
but it is a good starting point for experimentation
and feedback.

```bash
./configure --experimental-dtls
make -j{nproc}
./node --experimental-dtls my-dtls-app.js
```

Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode:Opus 4.6
PR-URL: https://github.com/nodejs/node/pull/63182
Fixes: https://github.com/nodejs/node/issues/61630
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2026-05-21 14:13:04 -07:00
Rafael Gonzaga dc99d18597 lib: handle --permission-audit when propagating flags
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs/node/pull/63047
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-05-06 19:21:11 +00:00
Felipe Coelho 1aebbdef06 src: skip JS callback for settled Promise.race losers
When Promise.race() or Promise.any() settles, V8 fires
kPromiseResolveAfterResolved / kPromiseRejectAfterResolved for each
"losing" promise. The PromiseRejectCallback in node_task_queue.cc was
crossing into JS for these events, but since the multipleResolves
event reached EOL in v25 (PR #58707), the JS handler does nothing.

The unnecessary C++-to-JS boundary crossings accumulate references in
a tight loop, causing OOM when using Promise.race() with
immediately-resolving promises.

Return early in PromiseRejectCallback() for these two events, skipping
the JS callback entirely. Also remove the dead case branches and
unused constant imports from the JS side.

Move early returns for kPromiseResolveAfterResolved and
kPromiseRejectAfterResolved before Number::New and CHECK(!callback),
avoiding unnecessary work. Remove dead NODE_DEFINE_CONSTANT exports
and fix comment placement in the JS switch statement. Bump test
--max-old-space-size from 20 to 64 for safety on instrumented builds.

Fixes: https://github.com/nodejs/node/issues/51452
Refs: https://github.com/nodejs/node/pull/60184
Refs: https://github.com/nodejs/node/pull/61960
PR-URL: https://github.com/nodejs/node/pull/62336
Refs: https://github.com/nodejs/node/issues/51452
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
2026-05-05 19:53:04 -07:00
Gürgün Dayıoğlu 44f9fc3643 process: handle rejections only when needed
Signed-off-by: Gürgün Dayıoğlu <hey@gurgun.day>
PR-URL: https://github.com/nodejs/node/pull/62919
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com>
2026-04-26 08:39:10 +00:00
Marco Ippolito 2071c44630 src: allow empty --experimental-config-file
PR-URL: https://github.com/nodejs/node/pull/61610
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2026-04-16 06:31:35 +00:00
cjihrigandPaolo Insogna d0fa608c07 lib,src,test,doc: add node:ffi module
PR-URL: https://github.com/nodejs/node/pull/62072
Co-authored-by: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Bryan English <bryan@bryanenglish.com>
2026-04-14 10:44:30 +01:00
James M Snell ae7c6a7767 stream: add stream/iter Implementation
Experimental implementation of https://stream-iter.jasnell.me/

Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-By: Claude/Opus 4.6
PR-URL: https://github.com/nodejs/node/pull/62066
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-03-27 19:55:08 -07:00
Matteo Collina a9da9ffc04 repl: remove dependency on domain module
Replace the domain-based error handling with AsyncLocalStorage and
setUncaughtExceptionCaptureCallback. This removes the REPL's dependency
on the deprecated domain module while preserving all existing behavior:

- Synchronous errors during eval are caught and displayed
- Async errors (setTimeout, promises, etc.) are caught via the
  uncaught exception capture callback
- Top-level await errors are caught and displayed
- The REPL continues operating after errors
- Multiple REPL instances can coexist with errors routed correctly

Changes:
- Use AsyncLocalStorage to track which REPL instance owns an async
  context, replacing domain's automatic async tracking
- Add setupExceptionCapture() to install
  setUncaughtExceptionCaptureCallback for catching async errors and
  routing them to the correct REPL
- Extract error handling logic into REPLServer.prototype._handleError()
- Wrap eval execution in replContext.run() for async context tracking
- Update newListener protection to check AsyncLocalStorage context
- Throw ERR_INVALID_ARG_VALUE if options.domain is passed

PR-URL: https://github.com/nodejs/node/pull/61227
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2026-03-06 15:38:36 +00:00
RafaelGSS a8eb690e0a src,permission: add --permission-audit
Add --permission-audit flag that enables the permission model in
warning-only mode. Instead of throwing ERR_ACCESS_DENIED, it emits
a message via diagnostics channel and allows the operation to
continue.

Publish permission check results to per-scope diagnostics channels
(e.g., node:permission-model:fs) so users can observe permission
decisions at runtime via diagnostics_channel.

Refs: https://github.com/nodejs/node/issues/59935
PR-URL: https://github.com/nodejs/node/pull/61869
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2026-02-26 00:48:26 +00:00
RafaelGSS 17bfd68a60 src: add C++ support for diagnostics channels
Add a C++ API for diagnostics channels that allows native code to check
for subscribers and publish messages without unnecessary JS boundary
crossings. Uses a shared AliasedUint32Array buffer between C++ and JS
to track subscriber counts per channel, enabling a fast inline check
(HasSubscribers) that reads the buffer directly.

PR-URL: https://github.com/nodejs/node/pull/61869
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2026-02-26 00:48:25 +00:00
Joyee Cheung 89555a0733 lib: remove top-level getOptionValue() calls in lib/internal/modules
PR-URL: https://github.com/nodejs/node/pull/61769
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
2026-02-19 12:52:23 +00:00
Mohamed Akram c1402c6644 process: do not truncate long strings in --print
Fixes: https://github.com/nodejs/node/issues/61337
PR-URL: https://github.com/nodejs/node/pull/61497
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
2026-01-25 21:41:07 +00:00
Matteo Collina fa70327610 lib: return undefined for localStorage without file
Make localStorage return undefined and emit a warning when
--localstorage-file is not provided. Mark the property as
non-enumerable to avoid breaking {...globalThis}.

Fixes: https://github.com/nodejs/node/issues/60303
PR-URL: https://github.com/nodejs/node/pull/61333
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-01-22 16:35:38 +00:00
Gürgün Dayıoğlu 012bf70908 process: optimize asyncHandledRejections by using FixedQueue
PR-URL: https://github.com/nodejs/node/pull/60854
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2026-01-02 11:40:05 +00:00
Gerhard Stöbich 926162a2ea async_hooks: enabledHooksExist shall return if hooks are enabled
Correct the implementaton of enabledHooksExist to return true if
there are enabled hooks.

Adapt callsites which used getHooksArrays() as workaround.

PR-URL: https://github.com/nodejs/node/pull/61054
Fixes: https://github.com/nodejs/node/issues/61019
Refs: https://github.com/nodejs/node/pull/59873
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
2025-12-31 14:45:20 +00:00
Gürgün Dayıoğlu a65421a679 process: preserve AsyncLocalStorage in queueMicrotask only when needed
PR-URL: https://github.com/nodejs/node/pull/60913
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
2025-12-21 01:12:15 +00:00
Livia Medeiros 46dc5d7c9f lib: prefer call() over apply() if argument list is not array
PR-URL: https://github.com/nodejs/node/pull/60796
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
2025-11-23 08:45:46 +00:00
Antoine du Hamel 3330e5caf1 doc,src,lib: clarify experimental status of Web Storage support
PR-URL: https://github.com/nodejs/node/pull/60708
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
2025-11-16 15:03:06 +00:00
Marco Ippolito 8e5c80d108 module: mark type stripping as stable
PR-URL: https://github.com/nodejs/node/pull/60600
Refs: https://github.com/nodejs/typescript/issues/24
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruy Adorno <ruy@vlt.sh>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
2025-11-08 09:36:45 +00:00
Joyee Cheung b19525a33c module: refactor and clarify async loader hook customizations
- This updates the comments that assume loader hooks must be async
- Differentiate the sync/async loader hook paths in naming
  `#customizations` is now `#asyncLoaderHooks` to make it clear
  it's from the async APIs.
- Differentiate the paths running on the loader hook thread
  (affects the loading of async other loader hooks and are async)
  v.s. paths on the main thread calling out to code on the loader
  hook thread (do not handle loading of other async loader hooks, and
  can be sync by blocking).
  - `Hooks` is now `AsyncLoaderHooksOnLoaderHookWorker`
  - `CustomizedModuleLoader` is now
    `AsyncLoaderHooksProxiedToLoaderHookWorker` and moved into
    `lib/internal/modules/esm/hooks.js` as it implements the same
    interface as `AsyncLoaderHooksOnLoaderHookWorker`
  - `HooksProxy` is now `AsyncLoaderHookWorker`
  - Adjust the JSDoc accordingly
- Clarify the "loader worker" as the "async loader hook worker"
  i.e. when there's no _async_ loader hook registered, there won't
  be this worker, to avoid the misconception that this worker
  is spawned unconditionally.
- The code run on the loader hook worker to process
  `--experimental-loader` is moved into
  `lib/internal/modules/esm/worker.js` for clarity.
- The initialization configuration `forceDefaultLoader` is split
  into `shouldSpawnLoaderHookWorker` and `shouldPreloadModules`
  as those can be separate.
- `--experimental-vm-modules` is now processed during pre-execution
  and no longer part of the initialization of the built-in ESM
  loader, as it only exposes the vm APIs of ESM, and is unrelated
  to built-in ESM loading.

PR-URL: https://github.com/nodejs/node/pull/60278
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
2025-10-23 13:42:23 +00:00
Gürgün Dayıoğlu 15278252bb lib: remove redundant destroyHook checks
PR-URL: https://github.com/nodejs/node/pull/60120
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
2025-10-08 12:11:43 +00:00
Shima Ryuhei 60f1a5d077 process: fix wrong asyncContext under unhandled-rejections=strict
Fixes: https://github.com/nodejs/node/issues/60034
PR-URL: https://github.com/nodejs/node/pull/60103
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
2025-10-04 02:12:19 +00:00
Richard Lau b8ea0e8e85 process: fix default env for process.execve
The `env` parameter for `process.execve` is documented to default
to `process.env`.

PR-URL: https://github.com/nodejs/node/pull/60029
Refs: https://github.com/nodejs/build/pull/4156
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
2025-10-01 12:47:07 +00:00
Daniel M Brasil 3312e4e946 src: unflag --experimental-webstorage by default
PR-URL: https://github.com/nodejs/node/pull/57666
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-09-25 11:59:58 +00:00