Commit 3c577146aa6 for nodejs

commit 3c577146aa641755179bd07fab9db1a18993091f
Author: Marco Ippolito <marcoippolito54@gmail.com>
Date:   Thu Oct 1 11:47:11 2026 +0200

    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>

diff --git a/doc/api/cli.md b/doc/api/cli.md
index 4e17d81169d..fb764c01edd 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -799,6 +799,163 @@ For example, to run a module with "development" resolutions:
 node -C development app.js
 ```

+### `--config-file=path`, `--config-file`
+
+<!-- YAML
+added:
+ - v23.10.0
+ - v22.16.0
+changes:
+  - version: REPLACEME
+    pr-url: https://github.com/nodejs/node/pull/66431
+    description: This flag was renamed from `--experimental-config-file` to
+                 `--config-file` and is now stable. `--experimental-config-file`
+                 and `--experimental-default-config-file` are kept as aliases.
+  - version: v26.7.0
+    pr-url: https://github.com/nodejs/node/pull/64516
+    description: Marked as release candidate.
+-->
+
+If present, Node.js will look for a configuration file at the specified path.
+If the path is not specified, Node.js will look for a `node.config.json` file
+in the current working directory.
+To specify a custom path, use the `--config-file=path` form.
+The space-separated `--config-file path` form is not supported.
+Node.js will read the configuration file and apply the settings. The
+configuration file should be a JSON file with the following structure. `vX.Y.Z`
+in the `$schema` must be replaced with the version of Node.js you are using or
+`latest-vX.x` for the latest version of that major release line.
+
+```json
+{
+  "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
+  "nodeOptions": {
+    "import": [
+      "amaro/strip"
+    ],
+    "watch-path": "src",
+    "watch-preserve-output": true
+  },
+  "test": {
+    "test-isolation": "process"
+  },
+  "watch": {
+    "watch-preserve-output": true
+  }
+}
+```
+
+The configuration file supports namespace-specific options:
+
+* The `nodeOptions` field contains CLI flags that are allowed in [`NODE_OPTIONS`][].
+
+* Namespace fields like `test`, `watch`, and `permission` contain configuration specific to that subsystem.
+
+The configuration file can target a specific Node.js major version with
+`nodeVersion`:
+
+```json
+{
+  "nodeVersion": 25,
+  "nodeOptions": {
+    "watch-path": "src"
+  }
+}
+```
+
+To keep multiple version-specific configurations in the same file, use the
+`configs` array. Node.js will use the first entry whose `nodeVersion` matches
+the current Node.js major version:
+
+```json
+{
+  "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
+  "configs": [
+    {
+      "nodeVersion": 25,
+      "config": {
+        "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
+        "nodeOptions": {
+          "watch-path": "src"
+        }
+      }
+    }
+  ]
+}
+```
+
+When `configs` is used, the top level may only contain `$schema` and
+`configs`. Each `configs` item must define an integer `nodeVersion` and an
+object `config`. A single top-level config does not require `nodeVersion`, but
+if present it must match the current Node.js major version.
+
+When a namespace is present in the
+configuration file, Node.js automatically enables the corresponding flag
+(e.g., `--test`, `--watch`, `--permission`). This allows you to configure
+subsystem-specific options without explicitly passing the flag on the command line.
+
+For example:
+
+```json
+{
+  "test": {
+    "test-isolation": "process"
+  }
+}
+```
+
+is equivalent to:
+
+```bash
+node --test --test-isolation=process
+```
+
+To disable the automatic flag while still using namespace options, you can
+explicitly set the flag to `false` within the namespace:
+
+```json
+{
+  "test": {
+    "test": false,
+    "test-isolation": "process"
+  }
+}
+```
+
+No-op flags are not supported.
+Not all V8 flags are currently supported.
+
+It is possible to use the [official JSON schema](../node-config-schema.json)
+to validate the configuration file, which may vary depending on the Node.js version.
+Each key in the configuration file corresponds to a flag that can be passed
+as a command-line argument. The value of the key is the value that would be
+passed to the flag.
+
+For example, the configuration file above is equivalent to
+the following command-line arguments:
+
+```bash
+node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
+```
+
+The priority in configuration is as follows:
+
+1. NODE\_OPTIONS and command-line options
+2. Dotenv NODE\_OPTIONS
+3. Configuration file
+
+Values in the configuration file will not override the values in the environment
+variables, command-line options, or the `NODE_OPTIONS` env file parsed by the
+`--env-file` flag.
+
+Keys cannot be duplicated within the same or different namespaces.
+
+The configuration parser will throw an error if the configuration file contains
+unknown keys or keys that cannot be used in a namespace.
+
+Node.js will not sanitize or perform validation on the user-provided configuration,
+so **NEVER** use untrusted configuration files.
+
 ### `--cpu-prof`

 <!-- YAML
@@ -1280,177 +1437,6 @@ added: v26.9.0

 Enable the experimental `node:bench` module and command-line benchmark runner.

-### `--experimental-config-file=path`, `--experimental-config-file`
-
-<!-- YAML
-added:
- - v23.10.0
- - v22.16.0
-changes:
-  - version: v26.7.0
-    pr-url: https://github.com/nodejs/node/pull/64516
-    description: Marked as release candidate.
--->
-
-> Stability: 1.2 - Release candidate
-
-If present, Node.js will look for a configuration file at the specified path.
-If the path is not specified, Node.js will look for a `node.config.json` file
-in the current working directory.
-To specify a custom path, use the `--experimental-config-file=path` form.
-The space-separated `--experimental-config-file path` form is not supported.
-The alias `--experimental-default-config-file` is equivalent to
-`--experimental-config-file` without an argument.
-Node.js will read the configuration file and apply the settings. The
-configuration file should be a JSON file with the following structure. `vX.Y.Z`
-in the `$schema` must be replaced with the version of Node.js you are using or
-`latest-vX.x` for the latest version of that major release line.
-
-```json
-{
-  "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
-  "nodeOptions": {
-    "import": [
-      "amaro/strip"
-    ],
-    "watch-path": "src",
-    "watch-preserve-output": true
-  },
-  "test": {
-    "test-isolation": "process"
-  },
-  "watch": {
-    "watch-preserve-output": true
-  }
-}
-```
-
-The configuration file supports namespace-specific options:
-
-* The `nodeOptions` field contains CLI flags that are allowed in [`NODE_OPTIONS`][].
-
-* Namespace fields like `test`, `watch`, and `permission` contain configuration specific to that subsystem.
-
-The configuration file can target a specific Node.js major version with
-`nodeVersion`:
-
-```json
-{
-  "nodeVersion": 25,
-  "nodeOptions": {
-    "watch-path": "src"
-  }
-}
-```
-
-To keep multiple version-specific configurations in the same file, use the
-`configs` array. Node.js will use the first entry whose `nodeVersion` matches
-the current Node.js major version:
-
-```json
-{
-  "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
-  "configs": [
-    {
-      "nodeVersion": 25,
-      "config": {
-        "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
-        "nodeOptions": {
-          "watch-path": "src"
-        }
-      }
-    }
-  ]
-}
-```
-
-When `configs` is used, the top level may only contain `$schema` and
-`configs`. Each `configs` item must define an integer `nodeVersion` and an
-object `config`. A single top-level config does not require `nodeVersion`, but
-if present it must match the current Node.js major version.
-
-When a namespace is present in the
-configuration file, Node.js automatically enables the corresponding flag
-(e.g., `--test`, `--watch`, `--permission`). This allows you to configure
-subsystem-specific options without explicitly passing the flag on the command line.
-
-For example:
-
-```json
-{
-  "test": {
-    "test-isolation": "process"
-  }
-}
-```
-
-is equivalent to:
-
-```bash
-node --test --test-isolation=process
-```
-
-To disable the automatic flag while still using namespace options, you can
-explicitly set the flag to `false` within the namespace:
-
-```json
-{
-  "test": {
-    "test": false,
-    "test-isolation": "process"
-  }
-}
-```
-
-No-op flags are not supported.
-Not all V8 flags are currently supported.
-
-It is possible to use the [official JSON schema](../node-config-schema.json)
-to validate the configuration file, which may vary depending on the Node.js version.
-Each key in the configuration file corresponds to a flag that can be passed
-as a command-line argument. The value of the key is the value that would be
-passed to the flag.
-
-For example, the configuration file above is equivalent to
-the following command-line arguments:
-
-```bash
-node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
-```
-
-The priority in configuration is as follows:
-
-1. NODE\_OPTIONS and command-line options
-2. Dotenv NODE\_OPTIONS
-3. Configuration file
-
-Values in the configuration file will not override the values in the environment
-variables, command-line options, or the `NODE_OPTIONS` env file parsed by the
-`--env-file` flag.
-
-Keys cannot be duplicated within the same or different namespaces.
-
-The configuration parser will throw an error if the configuration file contains
-unknown keys or keys that cannot be used in a namespace.
-
-Node.js will not sanitize or perform validation on the user-provided configuration,
-so **NEVER** use untrusted configuration files.
-
-### `--experimental-default-config-file`
-
-<!-- YAML
-added:
- - v23.10.0
- - v22.16.0
--->
-
-> Stability: 1.0 - Early development
-
-This flag is an alias for `--experimental-config-file` without an argument.
-If present, Node.js will look for a
-`node.config.json` file in the current working directory and load it as a
-configuration file.
-
 ### `--experimental-dtls`

 <!-- YAML
diff --git a/doc/api/permissions.md b/doc/api/permissions.md
index b531541f65f..27acf9d4c69 100644
--- a/doc/api/permissions.md
+++ b/doc/api/permissions.md
@@ -375,9 +375,9 @@ programs.
 #### Configuration file support

 In addition to passing permission flags on the command line, they can also be
-declared in a Node.js configuration file when using the experimental
-\[`--experimental-config-file`]\[] flag. Permission options must be placed inside
-the `permission` top-level object.
+declared in a Node.js configuration file when using the [`--config-file`][]
+flag. Permission options must be placed inside the `permission` top-level
+object.

 Example `node.config.json`:

@@ -400,7 +400,7 @@ When the `permission` namespace is present in the configuration file, Node.js
 automatically enables the `--permission` flag. Run with:

 ```console
-$ node --experimental-default-config-file app.js
+$ node --config-file app.js
 ```

 A configuration file, like the `NODE_OPTIONS` defined in an [`--env-file`][]
@@ -410,7 +410,7 @@ enable the Permission Model, the `allow-env` values these files define can only
 narrow the access that [`--allow-env`][] grants, and never widen it:

 ```console
-$ node --permission --allow-env=APP_* --experimental-config-file=node.config.json app.js
+$ node --permission --allow-env=APP_* --config-file=node.config.json app.js
 ```

 With `"allow-env": ["*"]` in `node.config.json`, only the variables starting with
@@ -539,6 +539,7 @@ Developers relying on --permission to sandbox untrusted code should be aware tha
 [`--allow-openssl-store`]: cli.md#--allow-openssl-store
 [`--allow-wasi`]: cli.md#--allow-wasi
 [`--allow-worker`]: cli.md#--allow-worker
+[`--config-file`]: cli.md#--config-filepath---config-file
 [`--env-file-if-exists`]: cli.md#--env-file-if-existsfile
 [`--env-file`]: cli.md#--env-filefile
 [`--permission-audit`]: cli.md#--permission-audit
diff --git a/doc/api/test.md b/doc/api/test.md
index 8cdfa884589..77bf17544df 100644
--- a/doc/api/test.md
+++ b/doc/api/test.md
@@ -885,10 +885,9 @@ test runner functionality:
 * `--experimental-test-tag-filter` - Filter expressions are validated by the parent
   process and re-emitted to child processes
 * `--watch` - Watch mode is handled at the parent level
-* `--experimental-default-config-file` - Config file loading is handled by the parent
 * `--test-reporter` - Reporting is managed by the parent process
 * `--test-reporter-destination` - Output destinations are controlled by the parent
-* `--experimental-config-file` - Config file paths are managed by the parent
+* `--config-file` - Config file paths are managed by the parent
 * `--test-randomize` - Randomization is managed by the parent process and
   propagated to child processes
 * `--test-random-seed` - Randomization seed is managed by the parent process and
@@ -5051,7 +5050,7 @@ test.describe('my suite', (suite) => {
 [`suite()`]: #suitename-options-fn
 [`test()`]: #testname-options-fn
 [code coverage]: #collecting-code-coverage
-[configuration files]: cli.md#--experimental-config-filepath---experimental-config-file
+[configuration files]: cli.md#--config-filepath---config-file
 [describe options]: #describename-options-fn
 [it options]: #testname-options-fn
 [module customization hooks]: module.md#customization-hooks
diff --git a/doc/node.1 b/doc/node.1
index 70488dff26c..a9ef1243fbb 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -480,6 +480,130 @@ For example, to run a module with "development" resolutions:
 node -C development app.js
 .Ed
 .
+.It Fl -config-file Ns = Ns Ar path , Fl -config-file
+If present, Node.js will look for a configuration file at the specified path.
+If the path is not specified, Node.js will look for a \fBnode.config.json\fR file
+in the current working directory.
+To specify a custom path, use the \fB--config-file=path\fR form.
+The space-separated \fB--config-file path\fR form is not supported.
+Node.js will read the configuration file and apply the settings. The
+configuration file should be a JSON file with the following structure. \fBvX.Y.Z\fR
+in the \fB$schema\fR must be replaced with the version of Node.js you are using or
+\fBlatest-vX.x\fR for the latest version of that major release line.
+.Bd -literal
+{
+  "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
+  "nodeOptions": {
+    "import": [
+      "amaro/strip"
+    ],
+    "watch-path": "src",
+    "watch-preserve-output": true
+  },
+  "test": {
+    "test-isolation": "process"
+  },
+  "watch": {
+    "watch-preserve-output": true
+  }
+}
+.Ed
+The configuration file supports namespace-specific options:
+.Bl -bullet
+.It
+The \fBnodeOptions\fR field contains CLI flags that are allowed in \fBNODE_OPTIONS\fR.
+.It
+Namespace fields like \fBtest\fR, \fBwatch\fR, and \fBpermission\fR contain configuration specific to that subsystem.
+.El
+The configuration file can target a specific Node.js major version with
+\fBnodeVersion\fR:
+.Bd -literal
+{
+  "nodeVersion": 25,
+  "nodeOptions": {
+    "watch-path": "src"
+  }
+}
+.Ed
+To keep multiple version-specific configurations in the same file, use the
+\fBconfigs\fR array. Node.js will use the first entry whose \fBnodeVersion\fR matches
+the current Node.js major version:
+.Bd -literal
+{
+  "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
+  "configs": [
+    {
+      "nodeVersion": 25,
+      "config": {
+        "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
+        "nodeOptions": {
+          "watch-path": "src"
+        }
+      }
+    }
+  ]
+}
+.Ed
+When \fBconfigs\fR is used, the top level may only contain \fB$schema\fR and
+\fBconfigs\fR. Each \fBconfigs\fR item must define an integer \fBnodeVersion\fR and an
+object \fBconfig\fR. A single top-level config does not require \fBnodeVersion\fR, but
+if present it must match the current Node.js major version.
+When a namespace is present in the
+configuration file, Node.js automatically enables the corresponding flag
+(e.g., \fB--test\fR, \fB--watch\fR, \fB--permission\fR). This allows you to configure
+subsystem-specific options without explicitly passing the flag on the command line.
+For example:
+.Bd -literal
+{
+  "test": {
+    "test-isolation": "process"
+  }
+}
+.Ed
+is equivalent to:
+.Bd -literal
+node --test --test-isolation=process
+.Ed
+To disable the automatic flag while still using namespace options, you can
+explicitly set the flag to \fBfalse\fR within the namespace:
+.Bd -literal
+{
+  "test": {
+    "test": false,
+    "test-isolation": "process"
+  }
+}
+.Ed
+No-op flags are not supported.
+Not all V8 flags are currently supported.
+It is possible to use the official JSON schema
+to validate the configuration file, which may vary depending on the Node.js version.
+Each key in the configuration file corresponds to a flag that can be passed
+as a command-line argument. The value of the key is the value that would be
+passed to the flag.
+For example, the configuration file above is equivalent to
+the following command-line arguments:
+.Bd -literal
+node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
+.Ed
+The priority in configuration is as follows:
+.Bl -bullet
+.It
+NODE_OPTIONS and command-line options
+.It
+Dotenv NODE_OPTIONS
+.It
+Configuration file
+.El
+Values in the configuration file will not override the values in the environment
+variables, command-line options, or the \fBNODE_OPTIONS\fR env file parsed by the
+\fB--env-file\fR flag.
+Keys cannot be duplicated within the same or different namespaces.
+The configuration parser will throw an error if the configuration file contains
+unknown keys or keys that cannot be used in a namespace.
+Node.js will not sanitize or perform validation on the user-provided configuration,
+so \fBNEVER\fR use untrusted configuration files.
+.
 .It Fl -cpu-prof
 Starts the V8 CPU profiler on start up, and writes the CPU profile to disk
 before exit.
@@ -722,138 +846,6 @@ Enable experimental import support for \fB.node\fR addons.
 .It Fl -experimental-bench
 Enable the experimental \fBnode:bench\fR module and command-line benchmark runner.
 .
-.It Fl -experimental-config-file Ns = Ns Ar path , Fl -experimental-config-file
-If present, Node.js will look for a configuration file at the specified path.
-If the path is not specified, Node.js will look for a \fBnode.config.json\fR file
-in the current working directory.
-To specify a custom path, use the \fB--experimental-config-file=path\fR form.
-The space-separated \fB--experimental-config-file path\fR form is not supported.
-The alias \fB--experimental-default-config-file\fR is equivalent to
-\fB--experimental-config-file\fR without an argument.
-Node.js will read the configuration file and apply the settings. The
-configuration file should be a JSON file with the following structure. \fBvX.Y.Z\fR
-in the \fB$schema\fR must be replaced with the version of Node.js you are using or
-\fBlatest-vX.x\fR for the latest version of that major release line.
-.Bd -literal
-{
-  "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
-  "nodeOptions": {
-    "import": [
-      "amaro/strip"
-    ],
-    "watch-path": "src",
-    "watch-preserve-output": true
-  },
-  "test": {
-    "test-isolation": "process"
-  },
-  "watch": {
-    "watch-preserve-output": true
-  }
-}
-.Ed
-The configuration file supports namespace-specific options:
-.Bl -bullet
-.It
-The \fBnodeOptions\fR field contains CLI flags that are allowed in \fBNODE_OPTIONS\fR.
-.It
-Namespace fields like \fBtest\fR, \fBwatch\fR, and \fBpermission\fR contain configuration specific to that subsystem.
-.El
-The configuration file can target a specific Node.js major version with
-\fBnodeVersion\fR:
-.Bd -literal
-{
-  "nodeVersion": 25,
-  "nodeOptions": {
-    "watch-path": "src"
-  }
-}
-.Ed
-To keep multiple version-specific configurations in the same file, use the
-\fBconfigs\fR array. Node.js will use the first entry whose \fBnodeVersion\fR matches
-the current Node.js major version:
-.Bd -literal
-{
-  "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
-  "configs": [
-    {
-      "nodeVersion": 25,
-      "config": {
-        "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
-        "nodeOptions": {
-          "watch-path": "src"
-        }
-      }
-    }
-  ]
-}
-.Ed
-When \fBconfigs\fR is used, the top level may only contain \fB$schema\fR and
-\fBconfigs\fR. Each \fBconfigs\fR item must define an integer \fBnodeVersion\fR and an
-object \fBconfig\fR. A single top-level config does not require \fBnodeVersion\fR, but
-if present it must match the current Node.js major version.
-When a namespace is present in the
-configuration file, Node.js automatically enables the corresponding flag
-(e.g., \fB--test\fR, \fB--watch\fR, \fB--permission\fR). This allows you to configure
-subsystem-specific options without explicitly passing the flag on the command line.
-For example:
-.Bd -literal
-{
-  "test": {
-    "test-isolation": "process"
-  }
-}
-.Ed
-is equivalent to:
-.Bd -literal
-node --test --test-isolation=process
-.Ed
-To disable the automatic flag while still using namespace options, you can
-explicitly set the flag to \fBfalse\fR within the namespace:
-.Bd -literal
-{
-  "test": {
-    "test": false,
-    "test-isolation": "process"
-  }
-}
-.Ed
-No-op flags are not supported.
-Not all V8 flags are currently supported.
-It is possible to use the official JSON schema
-to validate the configuration file, which may vary depending on the Node.js version.
-Each key in the configuration file corresponds to a flag that can be passed
-as a command-line argument. The value of the key is the value that would be
-passed to the flag.
-For example, the configuration file above is equivalent to
-the following command-line arguments:
-.Bd -literal
-node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
-.Ed
-The priority in configuration is as follows:
-.Bl -bullet
-.It
-NODE_OPTIONS and command-line options
-.It
-Dotenv NODE_OPTIONS
-.It
-Configuration file
-.El
-Values in the configuration file will not override the values in the environment
-variables, command-line options, or the \fBNODE_OPTIONS\fR env file parsed by the
-\fB--env-file\fR flag.
-Keys cannot be duplicated within the same or different namespaces.
-The configuration parser will throw an error if the configuration file contains
-unknown keys or keys that cannot be used in a namespace.
-Node.js will not sanitize or perform validation on the user-provided configuration,
-so \fBNEVER\fR use untrusted configuration files.
-.
-.It Fl -experimental-default-config-file
-This flag is an alias for \fB--experimental-config-file\fR without an argument.
-If present, Node.js will look for a
-\fBnode.config.json\fR file in the current working directory and load it as a
-configuration file.
-.
 .It Fl -experimental-dtls
 Enable experimental support for the DTLS protocol. See the
 dtls documentation for details.
diff --git a/lib/internal/bench_runner/cli.js b/lib/internal/bench_runner/cli.js
index 96930ca5687..48af55c9cf1 100644
--- a/lib/internal/bench_runner/cli.js
+++ b/lib/internal/bench_runner/cli.js
@@ -118,6 +118,7 @@ const kFilterArgValues = [
   '--bench-reporter-destination',
   '--bench-samples',
   '--bench-warmup',
+  '--config-file',
   '--experimental-config-file',
 ];
 const kIncompatibleExecArgv = new SafeSet([
@@ -652,7 +653,8 @@ function filterExecArgv(arg, index, args) {
   return !ArrayPrototypeIncludes(kFilterArgs, name) &&
     !ArrayPrototypeSome(kFilterArgValues, (option) => {
       return name === option ||
-        (option !== '--experimental-config-file' &&
+        (option !== '--config-file' &&
+         option !== '--experimental-config-file' &&
          index > 0 &&
          StringPrototypeIndexOf(args[index - 1], '=') === -1 &&
          getOptionName(args[index - 1]) === option);
diff --git a/lib/internal/debugger/inspect_helpers.js b/lib/internal/debugger/inspect_helpers.js
index 68d7901b38c..f77a4c8d189 100644
--- a/lib/internal/debugger/inspect_helpers.js
+++ b/lib/internal/debugger/inspect_helpers.js
@@ -113,7 +113,8 @@ function validateChildArgs(childArgs) {
     const arg = shiftArg();
     if (arg === '--') { break; }
     if (!isSynthetic &&
-        (arg === '--experimental-config-file' ||
+        (arg === '--config-file' ||
+         arg === '--experimental-config-file' ||
          arg === '--experimental-default-config-file')) {
       // ConfigReader rewrites these to an inline default path before parsing.
       continue;
diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js
index 21889b0304f..8d6b2b23dd1 100644
--- a/lib/internal/main/watch_mode.js
+++ b/lib/internal/main/watch_mode.js
@@ -68,7 +68,9 @@ for (let i = 0; i < process.execArgv.length; i++) {
     }
     continue;
   }
-  if (arg === '--experimental-config-file' ||
+  if (arg === '--config-file' ||
+      StringPrototypeStartsWith(arg, '--config-file=') ||
+      arg === '--experimental-config-file' ||
       StringPrototypeStartsWith(arg, '--experimental-config-file=')) {
     continue;
   }
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 9efccb40f8c..0f5aaf857ae 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -135,8 +135,6 @@ function prepareExecution(options) {
   initializeSourceMapsHandlers();
   initializeDeprecations();

-  initializeConfigFileSupport();
-
   // internal/dns/utils (and internal/net behind it) is only needed up front
   // to validate an explicit --dns-result-order or to register the resolver's
   // snapshot serialization; otherwise it is loaded with node:dns.
@@ -490,12 +488,6 @@ function setupOptionGatedBuiltins() {
   BuiltinModule.allowOptionGatedBuiltins(getOptionValue);
 }

-function initializeConfigFileSupport() {
-  if (getOptionValue('--experimental-config-file')) {
-    emitExperimentalWarning('--experimental-config-file');
-  }
-}
-
 function setupWebStorage() {
   if (getEmbedderOptions().noBrowserGlobals ||
       !getOptionValue('--experimental-webstorage')) {
diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js
index 98947c742b2..03ab8ee1c63 100644
--- a/lib/internal/test_runner/runner.js
+++ b/lib/internal/test_runner/runner.js
@@ -118,6 +118,7 @@ const kFilterArgValues = [
   '--test-reporter',
   '--test-reporter-destination',
   '--test-random-seed',
+  '--config-file',
   '--experimental-config-file',
 ];
 const kDiagnosticsFilterArgs = ['tests', 'suites', 'pass', 'fail', 'cancelled', 'skipped', 'todo', 'duration_ms'];
@@ -194,7 +195,8 @@ function filterExecArgv(arg, i, arr) {
   !ArrayPrototypeSome(kFilterArgValues, (p) => {
     return arg === p ||
       StringPrototypeStartsWith(arg, `${p}=`) ||
-      (p !== '--experimental-config-file' && i > 0 && arr[i - 1] === p);
+      (p !== '--config-file' && p !== '--experimental-config-file' &&
+       i > 0 && arr[i - 1] === p);
   });
 }

diff --git a/src/node_config_file.cc b/src/node_config_file.cc
index 73d2342d81f..0a44da48413 100644
--- a/src/node_config_file.cc
+++ b/src/node_config_file.cc
@@ -7,7 +7,10 @@

 namespace node {

-constexpr std::string_view kConfigFileFlag = "--experimental-config-file";
+constexpr std::string_view kConfigFileFlag = "--config-file";
+// TODO(marco-ippolito): Remove these aliases in a semver-major.
+constexpr std::string_view kExperimentalConfigFileFlag =
+    "--experimental-config-file";
 constexpr std::string_view kDefaultConfigFileFlag =
     "--experimental-default-config-file";
 constexpr std::string_view kDefaultConfigFileName = "node.config.json";
@@ -26,23 +29,20 @@ std::optional<std::string_view> ConfigReader::GetDataFromArgs(
   for (size_t i = 0; i < args->size(); ++i) {
     std::string& arg = (*args)[i];

-    if (arg == kConfigFileFlag) {
-      // --experimental-config-file
+    if (arg == kConfigFileFlag || arg == kExperimentalConfigFileFlag ||
+        arg == kDefaultConfigFileFlag) {
+      // --config-file, --experimental-config-file or
+      // --experimental-default-config-file
       arg = std::string(kConfigFileFlag) + "=" +
             std::string(kDefaultConfigFileName);
       result = kDefaultConfigFileName;
-    } else if (HasEqualsPrefix(arg, kConfigFileFlag)) {
-      // --experimental-config-file=path
-      std::string_view path =
-          std::string_view(arg).substr(kConfigFileFlag.size() + 1);
+    } else if (HasEqualsPrefix(arg, kConfigFileFlag) ||
+               HasEqualsPrefix(arg, kExperimentalConfigFileFlag)) {
+      // --config-file=path or --experimental-config-file=path
+      std::string_view path = std::string_view(arg).substr(arg.find('=') + 1);
       if (!path.empty()) {
         result = path;
       }
-    } else if (arg == kDefaultConfigFileFlag) {
-      // --experimental-default-config-file
-      arg = std::string(kConfigFileFlag) + "=" +
-            std::string(kDefaultConfigFileName);
-      result = kDefaultConfigFileName;
     } else if (HasEqualsPrefix(arg, kDefaultConfigFileFlag)) {
       invalid_default_config_file_argument_ = true;
     }
diff --git a/src/node_config_file.h b/src/node_config_file.h
index cc8d8e4c4c2..d6775aa8f69 100644
--- a/src/node_config_file.h
+++ b/src/node_config_file.h
@@ -23,7 +23,7 @@ namespace node {
 enum ParseResult { Valid, FileError, InvalidContent };

 // ConfigReader is the class that parses the configuration JSON file.
-// It reads the file provided by --experimental-config-file and
+// It reads the file provided by --config-file and
 // extracts the flags.
 class ConfigReader {
  public:
diff --git a/src/node_options.cc b/src/node_options.cc
index c46b3baa775..acd98e6b927 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1117,11 +1117,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
             "set environment variables from supplied file",
             &EnvironmentOptions::optional_env_file);
   Implies("--env-file-if-exists", "[has_env_file_string]");
-  AddOption("--experimental-config-file",
+  AddOption("--config-file",
             "set config file path",
-            &EnvironmentOptions::experimental_config_file_path,
+            &EnvironmentOptions::config_file_path,
             kDisallowedInEnvvar);
-  AddAlias("--experimental-default-config-file", "--experimental-config-file");
+  AddAlias("--experimental-config-file", "--config-file");
+  AddAlias("--experimental-default-config-file", "--config-file");
   AddOption("--experimental-package-map",
             "use the specified file for package map resolution",
             &EnvironmentOptions::experimental_package_map_path,
diff --git a/src/node_options.h b/src/node_options.h
index ae3ddeb3120..37e05101f56 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -150,7 +150,7 @@ class EnvironmentOptions : public Options {
   std::string watch_mode_kill_signal = "SIGTERM";
   std::string eval_string;
   std::string tls_keylog;
-  std::string experimental_config_file_path;
+  std::string config_file_path;
   std::string experimental_package_map_path;
   std::string vfs_load_source;
 #if HAVE_INSPECTOR
diff --git a/test/fixtures/test-runner/options-propagation/experimental-config-file.test.mjs b/test/fixtures/test-runner/options-propagation/config-file.test.mjs
similarity index 50%
rename from test/fixtures/test-runner/options-propagation/experimental-config-file.test.mjs
rename to test/fixtures/test-runner/options-propagation/config-file.test.mjs
index aa36ec2b52d..ade5a31be01 100644
--- a/test/fixtures/test-runner/options-propagation/experimental-config-file.test.mjs
+++ b/test/fixtures/test-runner/options-propagation/config-file.test.mjs
@@ -2,7 +2,7 @@ import { test } from 'node:test';
 import { strictEqual } from 'node:assert';
 import internal from 'internal/options';

-test('it should not receive --experimental-config-file option', () => {
-    const optionValue = internal.getOptionValue("--experimental-config-file");
+test('it should not receive --config-file option', () => {
+    const optionValue = internal.getOptionValue("--config-file");
     strictEqual(optionValue, '');
 })
diff --git a/test/parallel/test-bench-cli.js b/test/parallel/test-bench-cli.js
index df1c6edeb22..e36532ce2d0 100644
--- a/test/parallel/test-bench-cli.js
+++ b/test/parallel/test-bench-cli.js
@@ -428,7 +428,7 @@ if (common.hasInspector) {
   const result = spawnNode([
     '--no-warnings',
     '--experimental-bench',
-    `--experimental-config-file=${fixtures.path('bench-runner/node.config.json')}`,
+    `--config-file=${fixtures.path('bench-runner/node.config.json')}`,
     fixtures.path('bench-runner/a.cjs'),
   ]);
   assert.strictEqual(result.status, 0);
diff --git a/test/parallel/test-cli-node-options-docs.js b/test/parallel/test-cli-node-options-docs.js
index 534c99c04de..80caa29d426 100644
--- a/test/parallel/test-cli-node-options-docs.js
+++ b/test/parallel/test-cli-node-options-docs.js
@@ -122,6 +122,5 @@ for (const [, envVar, config] of nodeOptionsCC.matchAll(addOptionRE)) {

 // add alias handling
 manPagesOptions.delete('-trace-events-enabled');
-manPagesOptions.delete('-experimental-default-config-file');

 assert.strictEqual(manPagesOptions.size, 0, `Man page options not documented: ${[...manPagesOptions]}`);
diff --git a/test/parallel/test-cli-options-as-flags.js b/test/parallel/test-cli-options-as-flags.js
index ed87ba3e1fa..43f8df8a2ac 100644
--- a/test/parallel/test-cli-options-as-flags.js
+++ b/test/parallel/test-cli-options-as-flags.js
@@ -56,7 +56,7 @@ describe('getOptionsAsFlagsFromBinding', () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
       '--expose-internals',
-      `--experimental-config-file=${configFile}`,
+      `--config-file=${configFile}`,
       fixtureFile,
     ]);

@@ -75,7 +75,7 @@ describe('getOptionsAsFlagsFromBinding', () => {
       '--no-warnings',
       '--expose-internals',
       '--stack-trace-limit=512',
-      `--experimental-config-file=${configFile}`,
+      `--config-file=${configFile}`,
       fixtureFile,
     ]);

diff --git a/test/parallel/test-config-file.js b/test/parallel/test-config-file.js
index 104853cdcbe..d81b1703549 100644
--- a/test/parallel/test-config-file.js
+++ b/test/parallel/test-config-file.js
@@ -24,7 +24,7 @@ const onlyWithInspectorAndNodeOptions = {

 test('should handle non existing json', async () => {
   const result = await spawnPromisified(process.execPath, [
-    '--experimental-config-file=i-do-not-exist.json',
+    '--config-file=i-do-not-exist.json',
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Cannot read configuration from i-do-not-exist\.json: no such file or directory/);
@@ -35,7 +35,7 @@ test('should handle non existing json', async () => {

 test('should handle empty json', async () => {
   const result = await spawnPromisified(process.execPath, [
-    `--experimental-config-file=${fixtures.path('rc/empty.json')}`,
+    `--config-file=${fixtures.path('rc/empty.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Can't parse/);
@@ -47,7 +47,7 @@ test('should handle empty json', async () => {
 test('should handle empty object json', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/empty-object.json')}`,
+    `--config-file=${fixtures.path('rc/empty-object.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.strictEqual(result.stderr, '');
@@ -65,7 +65,7 @@ describe('runtime version checks', () => {

     return spawnPromisified(process.execPath, [
       '--no-warnings',
-      `--experimental-config-file=${configPath}`,
+      `--config-file=${configPath}`,
       '-p', 'http.maxHeaderSize',
     ]);
   }
@@ -284,17 +284,17 @@ describe('runtime version checks', () => {

 test('should parse boolean flag', onlyWithAmaroAndNodeOptions, async () => {
   const result = await spawnPromisified(process.execPath, [
-    `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+    `--config-file=${fixtures.path('rc/strip-types.json')}`,
     fixtures.path('typescript/ts/test-typescript.ts'),
   ]);
-  assert.match(result.stderr, /--experimental-config-file is an experimental feature and might change at any time/);
+  assert.strictEqual(result.stderr, '');
   assert.match(result.stdout, /Hello, TypeScript!/);
   assert.strictEqual(result.code, 0);
 });

 test('should parse boolean flag defaulted to true', onlyIfNodeOptionsSupport, async () => {
   const result = await spawnPromisified(process.execPath, [
-    `--experimental-config-file=${fixtures.path('rc/warnings-false.json')}`,
+    `--config-file=${fixtures.path('rc/warnings-false.json')}`,
     '-p', 'process.emitWarning("A warning")',
   ]);
   assert.strictEqual(result.stderr, '');
@@ -305,7 +305,7 @@ test('should parse boolean flag defaulted to true', onlyIfNodeOptionsSupport, as
 test('should throw an error when a flag is declared twice', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/override-property.json')}`,
+    `--config-file=${fixtures.path('rc/override-property.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Option --strip-types is already defined/);
@@ -316,7 +316,7 @@ test('should throw an error when a flag is declared twice', async () => {
 test('should not override env-file', onlyWithAmaroAndNodeOptions, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+    `--config-file=${fixtures.path('rc/strip-types.json')}`,
     '--env-file', fixtures.path('dotenv/node-options-no-tranform.env'),
     fixtures.path('typescript/ts/test-typescript.ts'),
   ]);
@@ -328,7 +328,7 @@ test('should not override env-file', onlyWithAmaroAndNodeOptions, async () => {
 test('should not override NODE_OPTIONS', onlyWithAmaro, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+    `--config-file=${fixtures.path('rc/strip-types.json')}`,
     fixtures.path('typescript/ts/test-typescript.ts'),
   ], {
     env: {
@@ -345,7 +345,7 @@ test('should not override CLI flags', onlyWithAmaro, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
     '--no-strip-types',
-    `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+    `--config-file=${fixtures.path('rc/strip-types.json')}`,
     fixtures.path('typescript/ts/test-typescript.ts'),
   ]);
   assert.match(result.stderr, /SyntaxError/);
@@ -356,7 +356,7 @@ test('should not override CLI flags', onlyWithAmaro, async () => {
 test('should parse array flag correctly', onlyIfNodeOptionsSupport, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/import.json')}`,
+    `--config-file=${fixtures.path('rc/import.json')}`,
     '--eval', 'setTimeout(() => console.log("D"),99)',
   ]);
   assert.strictEqual(result.stderr, '');
@@ -367,7 +367,7 @@ test('should parse array flag correctly', onlyIfNodeOptionsSupport, async () =>
 test('should validate invalid array flag', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/invalid-import.json')}`,
+    `--config-file=${fixtures.path('rc/invalid-import.json')}`,
     '--eval', 'setTimeout(() => console.log("D"),99)',
   ]);
   assert.match(result.stderr, /invalid-import\.json: invalid content/);
@@ -378,7 +378,7 @@ test('should validate invalid array flag', async () => {
 test('should validate array flag as string', onlyIfNodeOptionsSupport, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/import-as-string.json')}`,
+    `--config-file=${fixtures.path('rc/import-as-string.json')}`,
     '--eval', 'setTimeout(() => console.log("B"),99)',
   ]);
   assert.strictEqual(result.stderr, '');
@@ -389,7 +389,7 @@ test('should validate array flag as string', onlyIfNodeOptionsSupport, async ()
 test('should throw at unknown flag', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/unknown-flag.json')}`,
+    `--config-file=${fixtures.path('rc/unknown-flag.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Unknown or not allowed option some-unknown-flag for namespace nodeOptions/);
@@ -400,7 +400,7 @@ test('should throw at unknown flag', async () => {
 test('should throw at flag not available in NODE_OPTIONS', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/not-node-options-flag.json')}`,
+    `--config-file=${fixtures.path('rc/not-node-options-flag.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Unknown or not allowed option test for namespace nodeOptions/);
@@ -411,7 +411,7 @@ test('should throw at flag not available in NODE_OPTIONS', async () => {
 test('unsigned flag should be parsed correctly', onlyIfNodeOptionsSupport, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/numeric.json')}`,
+    `--config-file=${fixtures.path('rc/numeric.json')}`,
     '-p', 'http.maxHeaderSize',
   ]);
   assert.strictEqual(result.stderr, '');
@@ -422,7 +422,7 @@ test('unsigned flag should be parsed correctly', onlyIfNodeOptionsSupport, async
 test('numeric flag should not allow negative values', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/negative-numeric.json')}`,
+    `--config-file=${fixtures.path('rc/negative-numeric.json')}`,
     '-p', 'http.maxHeaderSize',
   ]);
   assert.match(result.stderr, /Invalid value for --max-http-header-size/);
@@ -434,7 +434,7 @@ test('numeric flag should not allow negative values', async () => {
 test('v8 flag should not be allowed in config file', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/v8-flag.json')}`,
+    `--config-file=${fixtures.path('rc/v8-flag.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /V8 flag --abort-on-uncaught-exception is currently not supported/);
@@ -446,7 +446,7 @@ test('string flag should be parsed correctly', onlyIfNodeOptionsSupport, async (
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
     '--test',
-    `--experimental-config-file=${fixtures.path('rc/string.json')}`,
+    `--config-file=${fixtures.path('rc/string.json')}`,
     fixtures.path('rc/test.js'),
   ]);
   assert.strictEqual(result.stderr, '');
@@ -458,7 +458,7 @@ test('host port flag should be parsed correctly', onlyWithInspectorAndNodeOption
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
     '--expose-internals',
-    `--experimental-config-file=${fixtures.path('rc/host-port.json')}`,
+    `--config-file=${fixtures.path('rc/host-port.json')}`,
     '-p', 'require("internal/options").getOptionValue("--inspect-port").port',
   ]);
   assert.strictEqual(result.stderr, '');
@@ -469,7 +469,7 @@ test('host port flag should be parsed correctly', onlyWithInspectorAndNodeOption
 test('--inspect=true should be parsed correctly', onlyWithInspectorAndNodeOptions, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/inspect-true.json')}`,
+    `--config-file=${fixtures.path('rc/inspect-true.json')}`,
     '--inspect-port', '0',
     '-p', 'require("node:inspector").url()',
   ]);
@@ -481,7 +481,7 @@ test('--inspect=true should be parsed correctly', onlyWithInspectorAndNodeOption
 test('--inspect=false should be parsed correctly', { skip: !process.features.inspector }, async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/inspect-false.json')}`,
+    `--config-file=${fixtures.path('rc/inspect-false.json')}`,
     '-p', 'require("node:inspector").url()',
   ]);
   assert.strictEqual(result.stderr, '');
@@ -492,7 +492,7 @@ test('--inspect=false should be parsed correctly', { skip: !process.features.ins
 test('no op flag should throw', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/no-op.json')}`,
+    `--config-file=${fixtures.path('rc/no-op.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /No-op flag --http-parser is currently not supported/);
@@ -504,7 +504,7 @@ test('no op flag should throw', async () => {
 test('should not allow users to sneak in a flag', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/sneaky-flag.json')}`,
+    `--config-file=${fixtures.path('rc/sneaky-flag.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /The number of NODE_OPTIONS doesn't match the number of flags in the config file/);
@@ -515,7 +515,7 @@ test('should not allow users to sneak in a flag', async () => {
 test('non object root', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/non-object-root.json')}`,
+    `--config-file=${fixtures.path('rc/non-object-root.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Root value unexpected not an object for/);
@@ -526,7 +526,7 @@ test('non object root', async () => {
 test('non object node options', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/non-object-node-options.json')}`,
+    `--config-file=${fixtures.path('rc/non-object-node-options.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /"nodeOptions" value unexpected for/);
@@ -537,7 +537,7 @@ test('non object node options', async () => {
 test('should throw correct error when a json is broken', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/broken.json')}`,
+    `--config-file=${fixtures.path('rc/broken.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Can't parse/);
@@ -549,7 +549,7 @@ test('should throw correct error when a json is broken', async () => {
 test('broken value in node_options', async () => {
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
-    `--experimental-config-file=${fixtures.path('rc/broken-node-options.json')}`,
+    `--config-file=${fixtures.path('rc/broken-node-options.json')}`,
     '-p', '"Hello, World!"',
   ]);
   assert.match(result.stderr, /Can't parse/);
@@ -571,11 +571,11 @@ test('should use node.config.json as default', onlyIfNodeOptionsSupport, async (
   assert.strictEqual(result.code, 0);
 });

-test('should use node.config.json when --experimental-config-file has no argument',
+test('should use node.config.json when --config-file has no argument',
      onlyIfNodeOptionsSupport, async () => {
        const result = await spawnPromisified(process.execPath, [
          '--no-warnings',
-         '--experimental-config-file',
+         '--config-file',
          '-p', 'http.maxHeaderSize',
        ], {
          cwd: fixtures.path('rc/default'),
@@ -589,7 +589,7 @@ test('should not treat the script path as a config file argument',
      onlyIfNodeOptionsSupport, async () => {
        const result = await spawnPromisified(process.execPath, [
          '--no-warnings',
-         '--experimental-config-file',
+         '--config-file',
          fixtures.path('printA.js'),
        ], {
          cwd: fixtures.path('rc/default'),
@@ -603,7 +603,7 @@ test('should treat a space-separated config file path as the script',
      onlyIfNodeOptionsSupport, async () => {
        const result = await spawnPromisified(process.execPath, [
          '--no-warnings',
-         '--experimental-config-file',
+         '--config-file',
          fixtures.path('rc/empty.json'),
          fixtures.path('printA.js'),
        ], {
@@ -617,16 +617,16 @@ test('should treat a space-separated config file path as the script',
        assert.strictEqual(result.code, 1);
      });

-test('should error when --experimental-config-file= has empty argument',
+test('should error when --config-file= has empty argument',
      onlyIfNodeOptionsSupport, async () => {
        const result = await spawnPromisified(process.execPath, [
          '--no-warnings',
-         '--experimental-config-file=',
+         '--config-file=',
          '-p', 'http.maxHeaderSize',
        ], {
          cwd: fixtures.path('rc/default'),
        });
-       assert.match(result.stderr, /--experimental-config-file= requires an argument/);
+       assert.match(result.stderr, /--config-file= requires an argument/);
        assert.strictEqual(result.code, 9);
      });

@@ -647,7 +647,7 @@ test('should override node.config.json when specified', onlyIfNodeOptionsSupport
   const result = await spawnPromisified(process.execPath, [
     '--no-warnings',
     '--experimental-default-config-file',
-    `--experimental-config-file=${fixtures.path('rc/default/override.json')}`,
+    `--config-file=${fixtures.path('rc/default/override.json')}`,
     '-p', 'http.maxHeaderSize',
   ], {
     cwd: fixtures.path('rc/default'),
@@ -657,11 +657,11 @@ test('should override node.config.json when specified', onlyIfNodeOptionsSupport
   assert.strictEqual(result.code, 0);
 });

-test('should work with --experimental-config-file=path',
+test('should work with --config-file=path',
      onlyIfNodeOptionsSupport, async () => {
        const result = await spawnPromisified(process.execPath, [
          '--no-warnings',
-         `--experimental-config-file=${fixtures.path('rc/default/node.config.json')}`,
+         `--config-file=${fixtures.path('rc/default/node.config.json')}`,
          '-p', 'http.maxHeaderSize',
        ]);
        assert.strictEqual(result.stderr, '');
@@ -669,12 +669,33 @@ test('should work with --experimental-config-file=path',
        assert.strictEqual(result.code, 0);
      });

+test('should support the --experimental-config-file alias',
+     onlyIfNodeOptionsSupport, async () => {
+       const withPath = await spawnPromisified(process.execPath, [
+         `--experimental-config-file=${fixtures.path('rc/default/node.config.json')}`,
+         '-p', 'http.maxHeaderSize',
+       ]);
+       assert.strictEqual(withPath.stderr, '');
+       assert.strictEqual(withPath.stdout, '10\n');
+       assert.strictEqual(withPath.code, 0);
+
+       const withoutPath = await spawnPromisified(process.execPath, [
+         '--experimental-config-file',
+         '-p', 'http.maxHeaderSize',
+       ], {
+         cwd: fixtures.path('rc/default'),
+       });
+       assert.strictEqual(withoutPath.stderr, '');
+       assert.strictEqual(withoutPath.stdout, '10\n');
+       assert.strictEqual(withoutPath.code, 0);
+     });
+
 test('should use last config file when multiple are specified',
      onlyIfNodeOptionsSupport, async () => {
        const result = await spawnPromisified(process.execPath, [
          '--no-warnings',
-         `--experimental-config-file=${fixtures.path('rc/default/node.config.json')}`,
-         `--experimental-config-file=${fixtures.path('rc/default/override.json')}`,
+         `--config-file=${fixtures.path('rc/default/node.config.json')}`,
+         `--config-file=${fixtures.path('rc/default/override.json')}`,
          '-p', 'http.maxHeaderSize',
        ]);
        assert.strictEqual(result.stderr, '');
@@ -686,7 +707,7 @@ test('should use default when next argument starts with dash',
      onlyIfNodeOptionsSupport, async () => {
        const result = await spawnPromisified(process.execPath, [
          '--no-warnings',
-         '--experimental-config-file',
+         '--config-file',
          '-p', 'http.maxHeaderSize',
        ], {
          cwd: fixtures.path('rc/default'),
@@ -724,7 +745,7 @@ describe('namespace-scoped options', () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
       '--expose-internals',
-      `--experimental-config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
+      `--config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
       '--no-test',
       '-p', 'require("internal/options").getOptionValue("--test-isolation")',
     ]);
@@ -736,7 +757,7 @@ describe('namespace-scoped options', () => {
   it('should throw an error when a namespace-scoped option is not recognised', async () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
-      `--experimental-config-file=${fixtures.path('rc/unknown-flag-namespace.json')}`,
+      `--config-file=${fixtures.path('rc/unknown-flag-namespace.json')}`,
       '-p', '"Hello, World!"',
     ]);
     assert.match(result.stderr, /Unknown or not allowed option unknown-flag for namespace test/);
@@ -747,7 +768,7 @@ describe('namespace-scoped options', () => {
   it('should throw an error when a namespace is not recognised', async () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
-      `--experimental-config-file=${fixtures.path('rc/unknown-namespace.json')}`,
+      `--config-file=${fixtures.path('rc/unknown-namespace.json')}`,
       '-p', '"Hello, World!"',
     ]);
     assert.match(result.stderr, /Unknown namespace an-invalid-namespace/);
@@ -759,7 +780,7 @@ describe('namespace-scoped options', () => {
   it('should allow the $schema field', async () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
-      `--experimental-config-file=${fixtures.path('rc/schema.json')}`,
+      `--config-file=${fixtures.path('rc/schema.json')}`,
       '-p', 'http.maxHeaderSize',
     ]);
     assert.strictEqual(result.stderr, '');
@@ -770,7 +791,7 @@ describe('namespace-scoped options', () => {
   it('should handle an empty namespace valid namespace', async () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
-      `--experimental-config-file=${fixtures.path('rc/empty-valid-namespace.json')}`,
+      `--config-file=${fixtures.path('rc/empty-valid-namespace.json')}`,
       '-p', '"Hello, World!"',
     ]);
     assert.strictEqual(result.stderr, '');
@@ -782,7 +803,7 @@ describe('namespace-scoped options', () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
       '--expose-internals',
-      `--experimental-config-file=${fixtures.path('rc/override-node-option-with-namespace.json')}`,
+      `--config-file=${fixtures.path('rc/override-node-option-with-namespace.json')}`,
       '-p', 'require("internal/options").getOptionValue("--test-isolation")',
     ]);
     assert.match(result.stderr, /Option --test-isolation is already defined/);
@@ -794,7 +815,7 @@ describe('namespace-scoped options', () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
       '--expose-internals',
-      `--experimental-config-file=${fixtures.path('rc/override-namespace.json')}`,
+      `--config-file=${fixtures.path('rc/override-namespace.json')}`,
       '-p', 'require("internal/options").getOptionValue("--test-isolation")',
     ]);
     assert.match(result.stderr, /Option --test-isolation is already defined/);
@@ -807,7 +828,7 @@ describe('namespace-scoped options', () => {
       '--no-warnings',
       '--expose-internals',
       '--test-isolation', 'process',
-      `--experimental-config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
+      `--config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
       '--no-test',
       '-p', 'require("internal/options").getOptionValue("--test-isolation")',
     ]);
@@ -822,7 +843,7 @@ describe('namespace-scoped options', () => {
       '--expose-internals',
       '--test-coverage-exclude', 'cli-pattern1',
       '--test-coverage-exclude', 'cli-pattern2',
-      `--experimental-config-file=${fixtures.path('rc/namespace-with-array.json')}`,
+      `--config-file=${fixtures.path('rc/namespace-with-array.json')}`,
       '--no-test',
       '-p', 'JSON.stringify(require("internal/options").getOptionValue("--test-coverage-exclude"))',
     ]);
@@ -844,7 +865,7 @@ describe('namespace-scoped options', () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
       '--expose-internals',
-      `--experimental-config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
+      `--config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
       '--no-test',
       '-p', 'require("internal/options").getOptionValue("--test-concurrency")',
     ]);
@@ -860,7 +881,7 @@ describe('namespace-scoped options', () => {
       '--no-warnings',
       '--expose-internals',
       '--test-concurrency', '2',
-      `--experimental-config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
+      `--config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
       '--no-test',
       '-p', 'require("internal/options").getOptionValue("--test-concurrency")',
     ]);
@@ -872,7 +893,7 @@ describe('namespace-scoped options', () => {
   it('should throw an error for removed "testRunner" namespace', async () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
-      `--experimental-config-file=${fixtures.path('rc/deprecated-testrunner-namespace.json')}`,
+      `--config-file=${fixtures.path('rc/deprecated-testrunner-namespace.json')}`,
       '-p', '"Hello, World!"',
     ]);
     assert.match(result.stderr, /the "testRunner" namespace has been removed\. Use "test" instead\./);
@@ -883,7 +904,7 @@ describe('namespace-scoped options', () => {
   it('should automatically enable --test flag when test namespace is present', async () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
-      `--experimental-config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
+      `--config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
       fixtures.path('rc/test.js'),
     ]);
     assert.strictEqual(result.code, 0);
@@ -894,7 +915,7 @@ describe('namespace-scoped options', () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
       '--expose-internals',
-      `--experimental-config-file=${fixtures.path('rc/permission-namespace.json')}`,
+      `--config-file=${fixtures.path('rc/permission-namespace.json')}`,
       '-p', 'require("internal/options").getOptionValue("--permission")',
     ]);
     assert.strictEqual(result.stderr, '');
@@ -906,7 +927,7 @@ describe('namespace-scoped options', () => {
     const result = await spawnPromisified(process.execPath, [
       '--no-warnings',
       '--expose-internals',
-      `--experimental-config-file=${fixtures.path('rc/test-namespace-explicit-false.json')}`,
+      `--config-file=${fixtures.path('rc/test-namespace-explicit-false.json')}`,
       '-p', 'require("internal/options").getOptionValue("--test")',
     ]);
     assert.strictEqual(result.stderr, '');
diff --git a/test/parallel/test-debugger-no-inspect-brk.js b/test/parallel/test-debugger-no-inspect-brk.js
index 611d28fd9f3..31a1edac0b8 100644
--- a/test/parallel/test-debugger-no-inspect-brk.js
+++ b/test/parallel/test-debugger-no-inspect-brk.js
@@ -120,6 +120,14 @@ assertSuccessfulProbe([
 // ConfigReader rewrites these bare options to use the default path without
 // consuming the following argument.
 Promise.all([
+  assert.rejects(
+    launchChildProcess([
+      '--config-file',
+      '--no-inspect-brk',
+      'probe.js',
+    ], '127.0.0.1', 0, () => {}),
+    incompatibleInspectBrk,
+  ),
   assert.rejects(
     launchChildProcess([
       '--experimental-config-file',
diff --git a/test/parallel/test-permission-config-file.mjs b/test/parallel/test-permission-config-file.mjs
index bfa9d6b0189..6b01f3741f3 100644
--- a/test/parallel/test-permission-config-file.mjs
+++ b/test/parallel/test-permission-config-file.mjs
@@ -13,7 +13,7 @@ describe('Permission model config file support', () => {
     {
       const result = await spawnPromisified(process.execPath, [
         '--permission',
-        `--experimental-config-file=${readOnlyConfigPath}`,
+        `--config-file=${readOnlyConfigPath}`,
         readTestPath,
       ]);
       assert.strictEqual(result.code, 0);
@@ -22,7 +22,7 @@ describe('Permission model config file support', () => {
     {
       const result = await spawnPromisified(process.execPath, [
         '--permission',
-        `--experimental-config-file=${readWriteConfigPath}`,
+        `--config-file=${readWriteConfigPath}`,
         writeTestPath,
       ]);
       assert.strictEqual(result.code, 0);
@@ -31,7 +31,7 @@ describe('Permission model config file support', () => {
     {
       const result = await spawnPromisified(process.execPath, [
         '--permission',
-        `--experimental-config-file=${readOnlyConfigPath}`,
+        `--config-file=${readOnlyConfigPath}`,
         writeTestPath,
       ]);
       assert.strictEqual(result.code, 1);
@@ -47,7 +47,7 @@ describe('Permission model config file support', () => {
     {
       const result = await spawnPromisified(process.execPath, [
         '--permission',
-        `--experimental-config-file=${configPath}`,
+        `--config-file=${configPath}`,
         childTestPath,
       ]);
       assert.strictEqual(result.code, 0);
@@ -56,7 +56,7 @@ describe('Permission model config file support', () => {
     {
       const result = await spawnPromisified(process.execPath, [
         '--permission',
-        `--experimental-config-file=${readOnlyConfigPath}`,
+        `--config-file=${readOnlyConfigPath}`,
         childTestPath,
       ]);
       assert.strictEqual(result.code, 1, result.stderr);
@@ -71,7 +71,7 @@ describe('Permission model config file support', () => {
     {
       const result = await spawnPromisified(process.execPath, [
         '--permission',
-        `--experimental-config-file=${configPath}`,
+        `--config-file=${configPath}`,
         '-p',
         'process.permission.has("net") && process.permission.has("inspector")',
       ]);
@@ -82,7 +82,7 @@ describe('Permission model config file support', () => {
     {
       const result = await spawnPromisified(process.execPath, [
         '--permission',
-        `--experimental-config-file=${readOnlyConfigPath}`,
+        `--config-file=${readOnlyConfigPath}`,
         '-p',
         'process.permission.has("net") + process.permission.has("inspector")',
       ]);
@@ -96,7 +96,7 @@ describe('Permission model config file support', () => {

     const result = await spawnPromisified(process.execPath, [
       '--permission',
-      `--experimental-config-file=${configPath}`,
+      `--config-file=${configPath}`,
       '--allow-fs-read=*',
       '-p',
       'process.permission.has("addon") && process.permission.has("wasi")',
@@ -110,7 +110,7 @@ describe('Permission model config file support', () => {

     const result = await spawnPromisified(process.execPath, [
       '--permission',
-      `--experimental-config-file=${configPath}`,
+      `--config-file=${configPath}`,
       '--allow-child-process',
       '--allow-fs-write=*',
       '-p',
diff --git a/test/parallel/test-permission-env-config-file.js b/test/parallel/test-permission-env-config-file.js
index 21a1f4d6126..a46278b8449 100644
--- a/test/parallel/test-permission-env-config-file.js
+++ b/test/parallel/test-permission-env-config-file.js
@@ -58,19 +58,19 @@ assert.deepStrictEqual(
   visible([
     '--permission',
     '--allow-env=PERMISSION_ENV_A',
-    `--experimental-config-file=${bothConfig}`,
+    `--config-file=${bothConfig}`,
   ]),
   ['PERMISSION_ENV_A']);

 assert.deepStrictEqual(
-  visible(['--permission', `--experimental-config-file=${allConfig}`]),
+  visible(['--permission', `--config-file=${allConfig}`]),
   []);

 assert.deepStrictEqual(
   visible([
     '--permission',
     '--allow-env=PERMISSION_ENV_PREFIX_*',
-    `--experimental-config-file=${prefixConfig}`,
+    `--config-file=${prefixConfig}`,
   ]),
   ['PERMISSION_ENV_PREFIX_DB_URL']);

@@ -86,7 +86,7 @@ assert.deepStrictEqual(
 // When only the configuration file enables the permission model, its
 // --allow-env values apply.
 assert.deepStrictEqual(
-  visible([`--experimental-config-file=${bothConfig}`]),
+  visible([`--config-file=${bothConfig}`]),
   ['PERMISSION_ENV_A', 'PERMISSION_ENV_B']);

 // The NODE_OPTIONS environment variable is not a file, and can grant access.
diff --git a/test/parallel/test-runner-cli.js b/test/parallel/test-runner-cli.js
index 5a5e6b9bdf1..28ad56a0a93 100644
--- a/test/parallel/test-runner-cli.js
+++ b/test/parallel/test-runner-cli.js
@@ -454,6 +454,8 @@ for (const isolation of ['none', 'process']) {
   // Should not propagate config file options to sub tests in isolation process.
   const fixturePath = join(testFixtures, 'options-propagation');
   const configFlagVariants = [
+    ['--config-file=node.config.json'],
+    ['--config-file'],
     ['--experimental-config-file=node.config.json'],
     ['--experimental-config-file'],
     ['--experimental-default-config-file'],
@@ -492,7 +494,7 @@ for (const isolation of ['none', 'process']) {
     const args = [
       '--test-reporter=tap',
       '--no-warnings',
-      `--experimental-config-file=node.config.json`,
+      `--config-file=node.config.json`,
       '--expose-internals',
       '--test',
     ];
diff --git a/test/parallel/test-runner-flag-propagation.js b/test/parallel/test-runner-flag-propagation.js
index 055d8b6d67c..afd7ae7a0ae 100644
--- a/test/parallel/test-runner-flag-propagation.js
+++ b/test/parallel/test-runner-flag-propagation.js
@@ -15,9 +15,11 @@ const runner = path.join(fixtureDir, 'runner.mjs');
 describe('test runner flag propagation', () => {
   describe('via command line', () => {
     const flagPropagationTests = [
-      ['--experimental-config-file=node.config.json', '', '', '--experimental-config-file',
+      ['--config-file=node.config.json', '', '', '--config-file',
+       'should not propagate --config-file to child tests'],
+      ['--experimental-config-file=node.config.json', '', '', '--config-file',
        'should not propagate --experimental-config-file to child tests'],
-      ['--experimental-default-config-file', '', '', '--experimental-config-file',
+      ['--experimental-default-config-file', '', '', '--config-file',
        'should not propagate --experimental-default-config-file to child tests'],
       ['--env-file', '.env', '.env'],
       ['--env-file-if-exists', '.env', '.env'],
@@ -108,7 +110,7 @@ describe('test runner flag propagation', () => {
           '--test-reporter=tap',
           '--no-warnings',
           '--expose-internals',
-          `--experimental-config-file=${configFile}`,
+          `--config-file=${configFile}`,
           runner,
           `--flag=${flagName}`,
           `--expected=${expectedValue}`,
diff --git a/test/sequential/test-watch-mode.mjs b/test/sequential/test-watch-mode.mjs
index 8607331a94a..1fe4f0597cb 100644
--- a/test/sequential/test-watch-mode.mjs
+++ b/test/sequential/test-watch-mode.mjs
@@ -874,7 +874,7 @@ process.on('message', (message) => {
     const file = createTmpFile();
     const configFile = createTmpFile(JSON.stringify({ watch: { 'watch': true } }), '.json');
     const { stderr, stdout } = await runWriteSucceed({
-      file, watchedFile: file, args: [`--experimental-config-file=${configFile}`, file], options: {
+      file, watchedFile: file, args: [`--config-file=${configFile}`, file], options: {
         timeout: 10000,
       },
     });
@@ -899,7 +899,7 @@ process.on('message', (message) => {
     const watchedFile = createTmpFile('', '.js', dir);
     const configFile = createTmpFile(JSON.stringify({ watch: { 'watch-path': [dir] } }), '.json', dir);

-    const args = [`--experimental-config-file=${configFile}`, file];
+    const args = [`--config-file=${configFile}`, file];
     const { stderr, stdout } = await runWriteSucceed({ file, watchedFile, args });

     assert.strictEqual(stderr, '');
@@ -924,7 +924,7 @@ process.on('message', (message) => {
     const { stderr, stdout } = await runWriteSucceed({
       file,
       watchedFile: file,
-      args: ['--experimental-default-config-file', file],
+      args: ['--config-file', file],
       options: {
         timeout: 10000,
         cwd: dir,