diff --git a/administrator/modules/mod_menu/mod_menu.php b/administrator/modules/mod_menu/mod_menu.php
deleted file mode 100644
index ee03a43dd0df7..0000000000000
--- a/administrator/modules/mod_menu/mod_menu.php
+++ /dev/null
@@ -1,23 +0,0 @@
-
- * @license GNU General Public License version 2 or later; see LICENSE.txt
- */
-
-\defined('_JEXEC') or die;
-
-use Joomla\CMS\Helper\ModuleHelper;
-use Joomla\Module\Menu\Administrator\Menu\CssMenu;
-
-$enabled = !$app->getInput()->getBool('hidemainmenu');
-
-$menu = new CssMenu($app);
-$root = $menu->load($params, $enabled);
-$root->level = 0;
-
-// Render the module layout
-require ModuleHelper::getLayoutPath('mod_menu', $params->get('layout', 'default'));
diff --git a/administrator/modules/mod_menu/mod_menu.xml b/administrator/modules/mod_menu/mod_menu.xml
index bc7d9cd4b654f..f78fbb68da710 100644
--- a/administrator/modules/mod_menu/mod_menu.xml
+++ b/administrator/modules/mod_menu/mod_menu.xml
@@ -11,7 +11,7 @@
MOD_MENU_XML_DESCRIPTION
Joomla\Module\Menu
- mod_menu.php
+ services
src
tmpl
diff --git a/administrator/modules/mod_menu/services/provider.php b/administrator/modules/mod_menu/services/provider.php
new file mode 100644
index 0000000000000..cf235e3c3bcbc
--- /dev/null
+++ b/administrator/modules/mod_menu/services/provider.php
@@ -0,0 +1,39 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+\defined('_JEXEC') or die;
+
+use Joomla\CMS\Extension\Service\Provider\Module;
+use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
+use Joomla\DI\Container;
+use Joomla\DI\ServiceProviderInterface;
+
+/**
+ * The administrator menu module service provider.
+ *
+ * @since __DEPLOY_VERSION__
+ */
+return new class () implements ServiceProviderInterface {
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Menu'));
+
+ $container->registerServiceProvider(new Module());
+ }
+};
diff --git a/administrator/modules/mod_menu/src/Dispatcher/Dispatcher.php b/administrator/modules/mod_menu/src/Dispatcher/Dispatcher.php
new file mode 100644
index 0000000000000..95f6e79362cb5
--- /dev/null
+++ b/administrator/modules/mod_menu/src/Dispatcher/Dispatcher.php
@@ -0,0 +1,46 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+namespace Joomla\Module\Menu\Administrator\Dispatcher;
+
+use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
+use Joomla\Module\Menu\Administrator\Menu\CssMenu;
+
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
+
+/**
+ * Dispatcher class for mod_menu
+ *
+ * @since __DEPLOY_VERSION__
+ */
+class Dispatcher extends AbstractModuleDispatcher
+{
+ /**
+ * Returns the layout data.
+ *
+ * @return array
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function getLayoutData()
+ {
+ $data = parent::getLayoutData();
+
+ $data['enabled'] = !$data['app']->getInput()->getBool('hidemainmenu');
+
+ $data['menu'] = new CssMenu($data['app']);
+ $data['root'] = $data['menu']->load($data['params'], $data['enabled']);
+ $data['root']->level = 0;
+
+ return $data;
+ }
+}
diff --git a/administrator/modules/mod_menu/src/Menu/CssMenu.php b/administrator/modules/mod_menu/src/Menu/CssMenu.php
index 7fe5e1eb4b1f6..0026469a139c6 100644
--- a/administrator/modules/mod_menu/src/Menu/CssMenu.php
+++ b/administrator/modules/mod_menu/src/Menu/CssMenu.php
@@ -16,7 +16,6 @@
use Joomla\CMS\Language\Associations;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Menu\AdministratorMenuItem;
-use Joomla\CMS\Table\Table;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Menus\Administrator\Helper\MenusHelper;
use Joomla\Registry\Registry;
@@ -231,7 +230,7 @@ protected function check($node, Registry $params)
$uri = clone Uri::getInstance();
$uri->setVar('recover_menu', 1);
- $table = Table::getInstance('MenuType');
+ $table = $this->application->bootComponent('com_menu')->getMVCFactory()->createTable('MenuType');
$menutype = $params->get('menutype');
$table->load(['menutype' => $menutype]);