diff --git a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
index d709cec522590e83fddbb19cf245a256e325a7d5..7045c25efcd51d7b0feacbe4fd87c60bbe5b0adf 100644
--- a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
+++ b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
@@ -334,9 +334,12 @@ abstract class AbstractFormElement extends AbstractNode
         if ($javaScriptEvaluation instanceof JavaScriptModuleInstruction) {
             if ($javaScriptEvaluation->shallLoadRequireJs()) {
                 // just use the module name and export-name
+                // @deprecated will be removed in TYPO3 v13.0
                 $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::forRequireJS(
                     $javaScriptEvaluation->getName(),
-                    $javaScriptEvaluation->getExportName()
+                    $javaScriptEvaluation->getExportName(),
+                    // silence deprecation error, has already been triggered by the original JavaScriptModuleInstruction instance
+                    true
                 )->invoke('registerCustomEvaluation', $name);
             } else {
                 // just use the module name and export-name
diff --git a/typo3/sysext/core/Classes/Controller/RequireJsController.php b/typo3/sysext/core/Classes/Controller/RequireJsController.php
index 40c41c9bd3777fe18739a9b4646723b0f72ac88b..c6d626b109291b52b59663d3a3d3348ce2d4352f 100644
--- a/typo3/sysext/core/Classes/Controller/RequireJsController.php
+++ b/typo3/sysext/core/Classes/Controller/RequireJsController.php
@@ -25,6 +25,8 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Handling requirejs client requests.
+ *
+ * @deprecated will be removed in TYPO3 v13.0.
  */
 class RequireJsController
 {
diff --git a/typo3/sysext/core/Classes/Page/JavaScriptModuleInstruction.php b/typo3/sysext/core/Classes/Page/JavaScriptModuleInstruction.php
index 409c067d6273617c35541fe0f40e698620f51847..ed4cf4cd8b257554cee8883efe54667395f171c0 100644
--- a/typo3/sysext/core/Classes/Page/JavaScriptModuleInstruction.php
+++ b/typo3/sysext/core/Classes/Page/JavaScriptModuleInstruction.php
@@ -23,6 +23,7 @@ class JavaScriptModuleInstruction implements \JsonSerializable
 {
     /**
      * Indicates a requireJS module shall be loaded.
+     * @deprecated will be removed in TYPO3 v13.0
      */
     public const FLAG_LOAD_REQUIRE_JS = 1;
 
@@ -61,11 +62,15 @@ class JavaScriptModuleInstruction implements \JsonSerializable
      * @param string $name RequireJS module name
      * @param string|null $exportName (optional) name used internally to export the module
      * @return self
+     * @deprecated will be removed in TYPO3 v13.0. Use JavaScriptModuleInstruction::create() instead.
      */
-    public static function forRequireJS(string $name, string $exportName = null): self
+    public static function forRequireJS(string $name, string $exportName = null, bool $internalCall = false): self
     {
         $target = GeneralUtility::makeInstance(static::class, $name, self::FLAG_LOAD_REQUIRE_JS);
         $target->exportName = $exportName;
+        if (!$internalCall) {
+            trigger_error('JavaScriptModuleInstruction::forRequireJS() is deprecated in favor of native ES6 modules, use JavaScriptModuleInstruction::create() instead. Support for RequireJS module loading will be removed in TYPO3 v13.0.', E_USER_DEPRECATED);
+        }
         return $target;
     }
 
@@ -183,6 +188,9 @@ class JavaScriptModuleInstruction implements \JsonSerializable
         return $this;
     }
 
+    /**
+     * @deprecated will be removed in TYPO3 v13.0
+     */
     public function shallLoadRequireJs(): bool
     {
         return ($this->flags & self::FLAG_LOAD_REQUIRE_JS) === self::FLAG_LOAD_REQUIRE_JS;
diff --git a/typo3/sysext/core/Classes/Page/PageRenderer.php b/typo3/sysext/core/Classes/Page/PageRenderer.php
index 7d851b1c087eef8f00b764e20e9b47d071aade4a..dbf0512f5f5e362e9b4b21dc9aa3f5ab05bcf91a 100644
--- a/typo3/sysext/core/Classes/Page/PageRenderer.php
+++ b/typo3/sysext/core/Classes/Page/PageRenderer.php
@@ -1578,9 +1578,13 @@ class PageRenderer implements SingletonInterface
      *
      * @param string $mainModuleName Must be in the form of "TYPO3/CMS/PackageName/ModuleName" e.g. "TYPO3/CMS/Backend/FormEngine"
      * @param string $callBackFunction loaded right after the requireJS loading, must be wrapped in function() {}
+     * @deprecated will be removed in TYPO3 v13.0. Use loadJavaScriptModule() instead, available since TYPO3 v12.0.
      */
-    public function loadRequireJsModule($mainModuleName, $callBackFunction = null)
+    public function loadRequireJsModule($mainModuleName, $callBackFunction = null, bool $internal = false)
     {
+        if (!$internal) {
+            trigger_error('PageRenderer->loadRequireJsModule is deprecated in favor of native ES6 modules, use loadJavaScriptModule() instead. Support for RequireJS module loading will be removed in TYPO3 v13.0.', E_USER_DEPRECATED);
+        }
         $inlineCodeKey = $mainModuleName;
         // make sure requireJS is initialized
         $this->loadRequireJs();
@@ -1593,7 +1597,7 @@ class PageRenderer implements SingletonInterface
         }
         if ($callBackFunction === null && $this->getApplicationType() === 'BE') {
             $this->javaScriptRenderer->addJavaScriptModuleInstruction(
-                JavaScriptModuleInstruction::forRequireJS($mainModuleName)
+                JavaScriptModuleInstruction::forRequireJS($mainModuleName, null, true)
             );
             return;
         }
diff --git a/typo3/sysext/core/Configuration/Backend/AjaxRoutes.php b/typo3/sysext/core/Configuration/Backend/AjaxRoutes.php
index 60a3b8a1d8a4a57067f737c2fa4818f302b74524..f75a7dd3424a63ce72a1d57e43ef0919130066ab 100644
--- a/typo3/sysext/core/Configuration/Backend/AjaxRoutes.php
+++ b/typo3/sysext/core/Configuration/Backend/AjaxRoutes.php
@@ -7,6 +7,7 @@ use TYPO3\CMS\Core\Controller\RequireJsController;
  */
 return [
     // dynamically load requirejs module definitions
+    // @deprecated will be removed in TYPO3 v13.0.
     'core_requirejs' => [
         'path' => '/core/requirejs',
         'access' => 'public',
diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-97057-DeprecateRequireJSSupport.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-97057-DeprecateRequireJSSupport.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3748b36b43a6497919cbd301922015c0b2dfe071
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-97057-DeprecateRequireJSSupport.rst
@@ -0,0 +1,75 @@
+.. include:: /Includes.rst.txt
+
+.. _deprecation-97057-1664653704:
+
+=================================================
+Deprecation: #97057 - Deprecate RequireJS support
+=================================================
+
+See :issue:`97057`
+
+Description
+===========
+
+The RequireJS project has been discontinued_ and was therefore
+replaced by native ECMAScript v6/v11 modules in TYPO3 in :issue:`96510`.
+
+The infrastructure for configuration and loading of RequireJS
+modules is now deprecated and will be removed in TYPO3 v13.
+
+
+Impact
+======
+
+Registering modules via :php:`'requireJsModules'` will still work.
+These modules will be loaded after modules registered via :php:`'javaScriptModules'`. Extensions that
+use :php:`'requireJsModules` will work as before but trigger a PHP :php:`E_USER_DEPRECATED` error.
+
+
+Affected installations
+======================
+
+Installations that register custom JavaScript modules for the TYPO3 backend.
+
+
+Migration
+=========
+
+Migrate your JavaScript from the AMD module format to native ES6 modules and register your configuration in :php:`Configuration/JavaScriptModules.php`, also see :issue:`96510` for more information:
+
+.. code-block:: php
+
+    # Configuration/JavaScriptModules.php
+    <?php
+
+    return [
+        'dependencies' => ['core', 'backend'],
+        'imports' => [
+            '@vendor/my-extension/' => 'EXT:my_extension/Resources/Public/JavaScript/',
+        ],
+    ];
+
+Then use :php:`TYPO3\CMS\Core\Page\PageRenderer::loadJavaScriptModules()` instead of :php:`TYPO3\CMS\Core\Page\PageRenderer::loadRequireJsModule()` to load the ES6 module:
+
+.. code-block:: php
+
+    // via PageRenderer
+    $this->packageRenderer->loadJavaScriptModule('@vendor/my-extension/example.js');
+
+
+In Fluid templates `includeJavaScriptModules` is to be used instead of `includeRequireJsModules`:
+
+In Fluid template the `includeJavaScriptModules` property of the
+:html:`<f:be.pageRenderer>` ViewHelper may be used:
+
+.. code-block:: xml
+
+   <f:be.pageRenderer
+      includeJavaScriptModules="{
+         0: '@vendor/my-extension/example.js'
+      }"
+   />
+
+.. _discontinued: https://github.com/requirejs/requirejs/issues/1816
+
+.. index:: Backend, JavaScript, NotScanned, ext:backend
diff --git a/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php b/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php
index 716abb281e9159a4cafb041442f9ad0f13dadf78..0aba10395ebd7c019da43ae0da7e5d89f6e34c4e 100644
--- a/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php
+++ b/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php
@@ -32,15 +32,15 @@ class JavaScriptRendererTest extends FunctionalTestCase
     {
         $subject = JavaScriptRenderer::create('anything.js');
         $subject->addJavaScriptModuleInstruction(
-            JavaScriptModuleInstruction::forRequireJS('TYPO3/CMS/Test*/')
+            JavaScriptModuleInstruction::create('@typo3/test/module.js')
                 ->invoke('test*/', 'arg*/')
         );
         $subject->addGlobalAssignment(['section*/' => ['key*/' => 'value*/']]);
         self::assertSame(
             '<script src="anything.js" async="async">'
                 . '/* [{"type":"globalAssignment","payload":{"section*\/":{"key*\/":"value*\/"}}},'
-                . '{"type":"javaScriptModuleInstruction","payload":{"name":"TYPO3\/CMS\/Test*\/","exportName":null,'
-                . '"flags":1,"items":[{"type":"invoke","method":"test*\/","args":["arg*\/"]}]}}] */</script>',
+                . '{"type":"javaScriptModuleInstruction","payload":{"name":"@typo3\/test\/module.js","exportName":null,'
+                . '"flags":2,"items":[{"type":"invoke","method":"test*\/","args":["arg*\/"]}]}}] */</script>',
             trim($subject->render())
         );
     }
diff --git a/typo3/sysext/dashboard/Classes/Controller/DashboardController.php b/typo3/sysext/dashboard/Classes/Controller/DashboardController.php
index da34c372a8a2f4ed513134b5c01b698a471d5d91..2ba53029af924030ab76d64efe1cda9af5bd5198 100644
--- a/typo3/sysext/dashboard/Classes/Controller/DashboardController.php
+++ b/typo3/sysext/dashboard/Classes/Controller/DashboardController.php
@@ -168,10 +168,12 @@ class DashboardController
         }
         foreach ($this->dashboardInitializationService->getRequireJsModules() as $requireJsModule) {
             if (is_array($requireJsModule)) {
-                $this->pageRenderer->loadRequireJsModule($requireJsModule[0], $requireJsModule[1]);
+                // Deprecation message is triggered by DashboardInitializationService::defineResourcesOfWidgets, and therefore silenced here.
+                $this->pageRenderer->loadRequireJsModule($requireJsModule[0], $requireJsModule[1], true);
             } else {
+                // Deprecation message is triggered by DashboardInitializationService::defineResourcesOfWidgets, and therefore silenced here.
                 $javaScriptRenderer->addJavaScriptModuleInstruction(
-                    JavaScriptModuleInstruction::forRequireJS($requireJsModule)
+                    JavaScriptModuleInstruction::forRequireJS($requireJsModule, null, true)
                 );
             }
         }
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/Menus/ActionMenuViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/Menus/ActionMenuViewHelper.php
index 84127af2c7ac7d793340e9ba87b8678f2344e536..7101cfd06e0d8a8ab4fed442c367f9ffae912b8a 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Be/Menus/ActionMenuViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/Menus/ActionMenuViewHelper.php
@@ -17,9 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Menus;
 
-use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
-use TYPO3\CMS\Core\Page\JavaScriptRenderer;
 use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
 use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
@@ -79,8 +78,8 @@ final class ActionMenuViewHelper extends AbstractTagBasedViewHelper
             'data-action-navigate' => '$value',
         ]);
         $this->tag->setContent($options);
-        return $this->loadRequireJsModule('TYPO3/CMS/Backend/GlobalEventHandler')
-            . '<div class="docheader-funcmenu">' . $this->tag->render() . '</div>';
+        $this->getPageRenderer()->loadJavaScriptModule('@typo3/backend/global-event-handler.js');
+        return '<div class="docheader-funcmenu">' . $this->tag->render() . '</div>';
     }
 
     /**
@@ -95,17 +94,8 @@ final class ActionMenuViewHelper extends AbstractTagBasedViewHelper
         return null;
     }
 
-    /**
-     * Renders `<script src="JavaScriptItemHandler.js">...</script>` for loading
-     * corresponding module. Using `JavaScriptRenderer` makes this independent
-     * from `PageRenderer` and its current application state.
-     */
-    protected function loadRequireJsModule(string $name): string
+    protected static function getPageRenderer(): PageRenderer
     {
-        $javaScriptRenderer = JavaScriptRenderer::create();
-        $javaScriptRenderer->addJavaScriptModuleInstruction(
-            JavaScriptModuleInstruction::forRequireJS($name)
-        );
-        return $javaScriptRenderer->render();
+        return GeneralUtility::makeInstance(PageRenderer::class);
     }
 }
diff --git a/typo3/sysext/form/Classes/Controller/FormEditorController.php b/typo3/sysext/form/Classes/Controller/FormEditorController.php
index 6cf23319e112e356202eb229ffdf462512bdc412..463732f84c49cf86d854d83d6ae8b4a642408dea 100644
--- a/typo3/sysext/form/Classes/Controller/FormEditorController.php
+++ b/typo3/sysext/form/Classes/Controller/FormEditorController.php
@@ -108,7 +108,7 @@ class FormEditorController extends AbstractBackendController
             $this->prototypeConfiguration['formEditor']['dynamicJavaScriptModules']['additionalViewModelModules'] ?? []
         );
         $additionalViewModelRequireJsModules = array_map(
-            static fn (string $name) => JavaScriptModuleInstruction::forRequireJS($name),
+            static fn (string $name) => JavaScriptModuleInstruction::forRequireJS($name, null, true),
             $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules']['additionalViewModelModules'] ?? []
         );
         if (count($additionalViewModelRequireJsModules) > 0) {
diff --git a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php
index 3aa246a757bb85620ea0022bc4e3f69dd870edcb..6f2e4cc63f7087f4d4e41f599c660851aa4461ee 100644
--- a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php
+++ b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php
@@ -152,8 +152,12 @@ class SetupModuleController
         $event = new AddJavaScriptModulesEvent();
         /** @var AddJavaScriptModulesEvent $event */
         $event = $this->eventDispatcher->dispatch($event);
+        foreach ($event->getJavaScriptModules() as $specifier) {
+            $this->pageRenderer->loadJavaScriptModule($specifier);
+        }
         foreach ($event->getModules() as $moduleName) {
-            $this->pageRenderer->loadRequireJsModule($moduleName);
+            // The deprecation is added in AddJavaScriptModulesEvent::addModule, and therefore silenced here.
+            $this->pageRenderer->loadRequireJsModule($moduleName, null, true);
         }
     }
 
diff --git a/typo3/sysext/setup/Classes/Event/AddJavaScriptModulesEvent.php b/typo3/sysext/setup/Classes/Event/AddJavaScriptModulesEvent.php
index 63ba207f9ed5599507046ab252e1e73dcaacdc70..440d8c2145c11f5a4668d941473f43da1f946e5e 100644
--- a/typo3/sysext/setup/Classes/Event/AddJavaScriptModulesEvent.php
+++ b/typo3/sysext/setup/Classes/Event/AddJavaScriptModulesEvent.php
@@ -22,19 +22,47 @@ namespace TYPO3\CMS\Setup\Event;
  */
 final class AddJavaScriptModulesEvent
 {
+    /**
+     * @var string[]
+     */
+    private array $javaScriptModules = [];
+
     /**
      * @var string[]
      */
     private array $modules = [];
 
+    /**
+     * @param string $specifier Bare module identifier like @my/package/filename.js
+     */
+    public function addJavaScriptModule(string $specifier): void
+    {
+        if (in_array($specifier, $this->javaScriptModules, true)) {
+            return;
+        }
+        $this->javaScriptModules[] = $specifier;
+    }
+
+    /**
+     * @deprecated will be removed in TYPO3 v13.0. Use addJavaScriptModule() instead, available since TYPO3 v12.0.
+     */
     public function addModule(string $moduleName): void
     {
+        trigger_error('AddJavaScriptModulesEvent->addModule is deprecated in favor of native ES6 modules and will be removed in TYPO3 v13.0. Use an ES6 module via addJavaScriptModule instead.', E_USER_DEPRECATED);
         if (in_array($moduleName, $this->modules, true)) {
             return;
         }
         $this->modules[] = $moduleName;
     }
 
+    /**
+     * @return string[]
+     */
+    public function getJavaScriptModules(): array
+    {
+        return $this->javaScriptModules;
+    }
+
     /**
      * @return string[]
      */