diff --git a/doc/api/cli.md b/doc/api/cli.md
index 6bc82659e48a3f..0ac58dba3510fb 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -395,12 +395,13 @@ Specify ways of the inspector web socket url exposure.
 By default inspector websocket url is available in stderr and under `/json/list`
 endpoint on `http://host:port/json/list`.
 
-### `--loader=file`
+### `--experimental-loader=module`
 <!-- YAML
 added: v9.0.0
 -->
 
-Specify the `file` of the custom [experimental ECMAScript Module][] loader.
+Specify the `module` of a custom [experimental ECMAScript Module][] loader.
+`module` may be either a path to a file, or an ECMAScript Module name.
 
 ### `--max-http-header-size=size`
 <!-- YAML
@@ -1001,6 +1002,7 @@ Node.js options that are allowed are:
 * `--enable-fips`
 * `--es-module-specifier-resolution`
 * `--experimental-exports`
+* `--experimental-loader`
 * `--experimental-modules`
 * `--experimental-policy`
 * `--experimental-repl-await`
@@ -1018,7 +1020,6 @@ Node.js options that are allowed are:
 * `--inspect-port`, `--debug-port`
 * `--inspect-publish-uid`
 * `--inspect`
-* `--loader`
 * `--max-http-header-size`
 * `--napi-modules`
 * `--no-deprecation`
diff --git a/doc/api/esm.md b/doc/api/esm.md
index b811f2c4cf7d3b..580528401629e2 100644
--- a/doc/api/esm.md
+++ b/doc/api/esm.md
@@ -632,7 +632,7 @@ would provide the exports interface for the instantiation of `module.wasm`.
 <!-- type=misc -->
 
 To customize the default module resolution, loader hooks can optionally be
-provided via a `--loader ./loader-name.mjs` argument to Node.js.
+provided via a `--experimental-loader ./loader-name.mjs` argument to Node.js.
 
 When hooks are used they only apply to ES module loading and not to any
 CommonJS modules loaded.
@@ -731,7 +731,7 @@ export async function resolve(specifier,
 With this loader, running:
 
 ```console
-NODE_OPTIONS='--experimental-modules --loader ./custom-loader.mjs' node x.js
+NODE_OPTIONS='--experimental-modules --experimental-loader ./custom-loader.mjs' node x.js
 ```
 
 would load the module `x.js` as an ES module with relative resolution support
diff --git a/doc/node.1 b/doc/node.1
index 0c8de4b75f6b57..ee0647ad6993e3 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -200,9 +200,9 @@ Default is
 V8 Inspector integration allows attaching Chrome DevTools and IDEs to Node.js instances for debugging and profiling.
 It uses the Chrome DevTools Protocol.
 .
-.It Fl -loader Ns = Ns Ar file
+.It Fl -experimental-loader Ns = Ns Ar module
 Specify the
-.Ar file
+.Ar module
 as a custom loader, to load
 .Fl -experimental-modules .
 .
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
index 6dd69c0c9b7888..79f1d97fbb306d 100644
--- a/lib/internal/bootstrap/pre_execution.js
+++ b/lib/internal/bootstrap/pre_execution.js
@@ -400,12 +400,12 @@ function initializeESMLoader() {
     // track of for different ESM modules.
     setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject);
     setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback);
-    const userLoader = getOptionValue('--loader');
-    // If --loader is specified, create a loader with user hooks. Otherwise
-    // create the default loader.
+    const userLoader = getOptionValue('--experimental-loader');
+    // If --experimental-loader is specified, create a loader with user hooks.
+    // Otherwise create the default loader.
     if (userLoader) {
       const { emitExperimentalWarning } = require('internal/util');
-      emitExperimentalWarning('--loader');
+      emitExperimentalWarning('--experimental-loader');
     }
     esm.initializeLoader(process.cwd(), userLoader);
   }
diff --git a/src/node_options.cc b/src/node_options.cc
index 98049453d8b24e..570603140abef4 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -114,7 +114,8 @@ void PerIsolateOptions::CheckOptions(std::vector<std::string>* errors) {
 
 void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) {
   if (!userland_loader.empty() && !experimental_modules) {
-    errors->push_back("--loader requires --experimental-modules be enabled");
+    errors->push_back("--experimental-loader requires "
+                      "--experimental-modules be enabled");
   }
   if (has_policy_integrity_string && experimental_policy.empty()) {
     errors->push_back("--policy-integrity requires "
@@ -315,6 +316,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
             "experimental support for exports in package.json",
             &EnvironmentOptions::experimental_exports,
             kAllowedInEnvironment);
+  AddOption("--experimental-loader",
+            "(with --experimental-modules) use the specified file as a "
+            "custom loader",
+            &EnvironmentOptions::userland_loader,
+            kAllowedInEnvironment);
+  AddAlias("--loader", "--experimental-loader");
   AddOption("--experimental-modules",
             "experimental ES Module support and caching modules",
             &EnvironmentOptions::experimental_modules,
@@ -376,11 +383,6 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
             "set module type for string input",
             &EnvironmentOptions::module_type,
             kAllowedInEnvironment);
-  AddOption("--loader",
-            "(with --experimental-modules) use the specified file as a "
-            "custom loader",
-            &EnvironmentOptions::userland_loader,
-            kAllowedInEnvironment);
   AddOption("--es-module-specifier-resolution",
             "Select extension resolution algorithm for es modules; "
             "either 'explicit' (default) or 'node'",
diff --git a/test/es-module/test-esm-example-loader.js b/test/es-module/test-esm-example-loader.js
index c3ba95f2280857..0da1d34d2ad6fc 100644
--- a/test/es-module/test-esm-example-loader.js
+++ b/test/es-module/test-esm-example-loader.js
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/example-loader.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/example-loader.mjs
 /* eslint-disable node-core/require-common-first, node-core/required-modules */
 import assert from 'assert';
 import ok from '../fixtures/es-modules/test-esm-ok.mjs';
diff --git a/test/es-module/test-esm-loader-dependency.mjs b/test/es-module/test-esm-loader-dependency.mjs
index 9cb2856009618a..dadc3bd84ae1d3 100644
--- a/test/es-module/test-esm-loader-dependency.mjs
+++ b/test/es-module/test-esm-loader-dependency.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-with-dep.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-with-dep.mjs
 /* eslint-disable node-core/require-common-first, node-core/required-modules */
 import '../fixtures/es-modules/test-esm-ok.mjs';
 
diff --git a/test/es-module/test-esm-loader-invalid-format.mjs b/test/es-module/test-esm-loader-invalid-format.mjs
index e4e4e30f5cc2e8..9e26d646d479a1 100644
--- a/test/es-module/test-esm-loader-invalid-format.mjs
+++ b/test/es-module/test-esm-loader-invalid-format.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-invalid-format.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-invalid-format.mjs
 import { expectsError, mustCall } from '../common/index.mjs';
 import assert from 'assert';
 
diff --git a/test/es-module/test-esm-loader-invalid-url.mjs b/test/es-module/test-esm-loader-invalid-url.mjs
index 44bacf9347c840..f42900c58e049c 100644
--- a/test/es-module/test-esm-loader-invalid-url.mjs
+++ b/test/es-module/test-esm-loader-invalid-url.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-invalid-url.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-invalid-url.mjs
 import { expectsError, mustCall } from '../common/index.mjs';
 import assert from 'assert';
 
diff --git a/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs b/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs
index 50fbf0c83ecea9..5767af7affe1fa 100644
--- a/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs
+++ b/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/missing-dynamic-instantiate-hook.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/missing-dynamic-instantiate-hook.mjs
 import { expectsError } from '../common/index.mjs';
 
 import('test').catch(expectsError({
diff --git a/test/es-module/test-esm-named-exports.mjs b/test/es-module/test-esm-named-exports.mjs
index 8b7c429b3d802d..6c8030826970a8 100644
--- a/test/es-module/test-esm-named-exports.mjs
+++ b/test/es-module/test-esm-named-exports.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs
 import '../common/index.mjs';
 import { readFile } from 'fs';
 import assert from 'assert';
diff --git a/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs b/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs
index b9b2860dffa069..1dcae4b8aef4a8 100644
--- a/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs
+++ b/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs
@@ -1,3 +1,3 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs
 /* eslint-disable node-core/require-common-first, node-core/required-modules */
 import './not-found.js';
diff --git a/test/es-module/test-esm-preserve-symlinks-not-found.mjs b/test/es-module/test-esm-preserve-symlinks-not-found.mjs
index 1dbdfa03e69139..68e1b53eeb1d75 100644
--- a/test/es-module/test-esm-preserve-symlinks-not-found.mjs
+++ b/test/es-module/test-esm-preserve-symlinks-not-found.mjs
@@ -1,3 +1,3 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs
 /* eslint-disable node-core/require-common-first, node-core/required-modules */
 import './not-found.mjs';
diff --git a/test/es-module/test-esm-resolve-hook.mjs b/test/es-module/test-esm-resolve-hook.mjs
index bbf6c80cdab344..00c8e440f42964 100644
--- a/test/es-module/test-esm-resolve-hook.mjs
+++ b/test/es-module/test-esm-resolve-hook.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/js-loader.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/js-loader.mjs
 /* eslint-disable node-core/require-common-first, node-core/required-modules */
 import { namedExport } from '../fixtures/es-module-loaders/js-as-esm.js';
 import assert from 'assert';
diff --git a/test/es-module/test-esm-shared-loader-dep.mjs b/test/es-module/test-esm-shared-loader-dep.mjs
index 00ba1ec31a226a..b02e557d34bc29 100644
--- a/test/es-module/test-esm-shared-loader-dep.mjs
+++ b/test/es-module/test-esm-shared-loader-dep.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-shared-dep.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-shared-dep.mjs
 import { createRequire } from '../common/index.mjs';
 
 import assert from 'assert';
diff --git a/test/parallel/test-loaders-unknown-builtin-module.mjs b/test/parallel/test-loaders-unknown-builtin-module.mjs
index b7d815c812ce3f..b0b1d400e6904e 100644
--- a/test/parallel/test-loaders-unknown-builtin-module.mjs
+++ b/test/parallel/test-loaders-unknown-builtin-module.mjs
@@ -1,4 +1,4 @@
-// Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-unknown-builtin-module.mjs
+// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-unknown-builtin-module.mjs
 import { expectsError, mustCall } from '../common/index.mjs';
 import assert from 'assert';
 
diff --git a/test/parallel/test-process-env-allowed-flags-are-documented.js b/test/parallel/test-process-env-allowed-flags-are-documented.js
index a60f6bbecf69cf..2e0d67eefcb242 100644
--- a/test/parallel/test-process-env-allowed-flags-are-documented.js
+++ b/test/parallel/test-process-env-allowed-flags-are-documented.js
@@ -87,6 +87,7 @@ const undocumented = difference(process.allowedNodeEnvironmentFlags,
 assert(undocumented.delete('--debug-arraybuffer-allocations'));
 assert(undocumented.delete('--experimental-worker'));
 assert(undocumented.delete('--no-node-snapshot'));
+assert(undocumented.delete('--loader'));
 
 assert.strictEqual(undocumented.size, 0,
                    'The following options are not documented as allowed in ' +