diff --git a/core/core.services.yml b/core/core.services.yml
index 459503e..7328469 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -497,7 +497,7 @@ services:
     arguments: ['@container.namespaces', '@cache.discovery', '@module_handler']
   module_handler:
     class: Drupal\Core\Extension\ModuleHandler
-    arguments: ['@app.root', '%container.modules%', '@cache.bootstrap']
+    arguments: ['@app.root', '%container.modules%', '@cache.bootstrap', '@config.factory']
   module_installer:
     class: Drupal\Core\Extension\ModuleInstaller
     tags:
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index a869d90..12bf0d7 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1770,7 +1770,7 @@ function install_finished(&$install_state) {
   $profile = drupal_get_profile();
 
   // Installation profiles are always loaded last.
-  module_set_weight($profile, 1000);
+  \Drupal::moduleHandler()->setWeight($profile, 1000);
 
   // Build the router once after installing all modules.
   // This would normally happen upon KernelEvents::TERMINATE, but since the
diff --git a/core/includes/module.inc b/core/includes/module.inc
index e3f446c..38b3fbe 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -170,12 +170,15 @@ function drupal_required_modules() {
  *
  * The weight of uninstalled modules cannot be changed.
  *
+ * @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0.
+ *
  * @param string $module
  *   The name of the module (without the .module extension).
  * @param int $weight
  *   An integer representing the weight of the module.
  */
 function module_set_weight($module, $weight) {
+  @trigger_error('module_set_weight() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0.', E_USER_DEPRECATED);
   $extension_config = \Drupal::configFactory()->getEditable('core.extension');
   if ($extension_config->get("module.$module") !== NULL) {
     // Pre-cast the $weight to an integer so that we can save this without using
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index d8d3608..5de1c11 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Graph\Graph;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
 
 /**
  * Class that manages modules in a Drupal installation.
@@ -71,6 +72,13 @@ class ModuleHandler implements ModuleHandlerInterface {
   protected $cacheNeedsWriting = FALSE;
 
   /**
+   * The config.factory service.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
    * List of alter hook implementations keyed by hook name(s).
    *
    * @var array
@@ -102,17 +110,20 @@ class ModuleHandler implements ModuleHandlerInterface {
    *   %container.modules% parameter being set up by DrupalKernel.
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
    *   Cache backend for storing module hook implementation information.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config.factory service.
    *
    * @see \Drupal\Core\DrupalKernel
    * @see \Drupal\Core\CoreServiceProvider
    */
-  public function __construct($root, array $module_list, CacheBackendInterface $cache_backend) {
+  public function __construct($root, array $module_list, CacheBackendInterface $cache_backend, ConfigFactoryInterface $config_factory) {
     $this->root = $root;
     $this->moduleList = [];
     foreach ($module_list as $name => $module) {
       $this->moduleList[$name] = new Extension($this->root, $module['type'], $module['pathname'], $module['filename']);
     }
     $this->cacheBackend = $cache_backend;
+    $this->configFactory = $config_factory;
   }
 
   /**
@@ -503,6 +514,59 @@ public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
   }
 
   /**
+   * Sets weight of a particular module.
+   *
+   * The weight of uninstalled modules cannot be changed.
+   *
+   * @param string $module
+   *   The name of the module (without the .module extension).
+   * @param int $weight
+   *   An integer representing the weight of the module.
+   *
+   * @return $this
+   */
+  function setWeight($module, $weight) {
+    $extension_config = $this->configFactory->getEditable('core.extension');
+    if ($extension_config->get("module.$module") !== NULL) {
+      // Pre-cast the $weight to an integer so that we can save this without using
+      // schema. This is a performance improvement for module installation.
+      $extension_config
+        ->set("module.$module", (int) $weight)
+        ->set('module', module_config_sort($extension_config->get('module')))
+        ->save(TRUE);
+
+      // Prepare the new module list, sorted by weight, including filenames.
+      // @see \Drupal\Core\Extension\ModuleInstaller::install()
+      $current_module_filenames = $this->getModuleList();
+      $current_modules = array_fill_keys(array_keys($current_module_filenames), 0);
+      $current_modules = module_config_sort(array_merge($current_modules, $extension_config->get('module')));
+      $module_filenames = [];
+      foreach ($current_modules as $name => $weight) {
+        $module_filenames[$name] = $current_module_filenames[$name];
+      }
+      // Update the module list in the extension handler.
+      $this->setModuleList($module_filenames);
+
+      return $this;
+    }
+  }
+
+  /**
+   * Gets weight of a particular module.
+   *
+   * @param string $module
+   *   The name of the module (without the .module extension).
+   *
+   * @return int|null
+   *   An integer representing the weight of the module, or NULL if the named
+   *   module is not installed.
+   */
+  function getWeight($module) {
+    $extension_config = $this->configFactory->get('core.extension');
+    return $extension_config->get("module.$module");
+  }
+
+  /**
    * Provides information about modules' implementations of a hook.
    *
    * @param string $hook
diff --git a/core/modules/content_translation/content_translation.install b/core/modules/content_translation/content_translation.install
index 0e47270..b60a0de 100644
--- a/core/modules/content_translation/content_translation.install
+++ b/core/modules/content_translation/content_translation.install
@@ -15,7 +15,7 @@
 function content_translation_install() {
   // Assign a fairly low weight to ensure our implementation of
   // hook_module_implements_alter() is run among the last ones.
-  module_set_weight('content_translation', 10);
+  \Drupal::moduleHandler()->setWeight('content_translation', 10);
 
   // Translation works when at least two languages are added.
   if (count(\Drupal::languageManager()->getLanguages()) < 2) {
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 4a16a89..7aac725 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -13,7 +13,7 @@
  */
 function forum_install() {
   // Set the weight of the forum.module to 1 so it is loaded after the taxonomy.module.
-  module_set_weight('forum', 1);
+  \Drupal::moduleHandler()->setWeight('forum', 1);
   // Do not allow to delete the forum's node type machine name.
   $locked = \Drupal::state()->get('node.type.locked');
   $locked['forum'] = 'forum';
diff --git a/core/modules/menu_link_content/menu_link_content.install b/core/modules/menu_link_content/menu_link_content.install
index 43c75ec..dc2f851 100644
--- a/core/modules/menu_link_content/menu_link_content.install
+++ b/core/modules/menu_link_content/menu_link_content.install
@@ -14,5 +14,5 @@ function menu_link_content_install() {
   // @todo remove this when the cache clearing is moved to path module or if
   //   caching is removed for path aliases due to
   //   https://www.drupal.org/node/1965074
-  module_set_weight('menu_link_content', 1);
+  \Drupal::moduleHandler()->setWeight('menu_link_content', 1);
 }
diff --git a/core/modules/menu_link_content/tests/src/Kernel/MenuLinkContentCacheabilityBubblingTest.php b/core/modules/menu_link_content/tests/src/Kernel/MenuLinkContentCacheabilityBubblingTest.php
index 414ecde..9f55ce6 100644
--- a/core/modules/menu_link_content/tests/src/Kernel/MenuLinkContentCacheabilityBubblingTest.php
+++ b/core/modules/menu_link_content/tests/src/Kernel/MenuLinkContentCacheabilityBubblingTest.php
@@ -37,7 +37,7 @@ protected function setUp() {
 
     // Ensure that the weight of module_link_content is higher than system.
     // @see menu_link_content_install()
-    module_set_weight('menu_link_content', 1);
+    \Drupal::moduleHandler()->setWeight('menu_link_content', 1);
   }
 
   /**
diff --git a/core/modules/menu_link_content/tests/src/Kernel/PathAliasMenuLinkContentTest.php b/core/modules/menu_link_content/tests/src/Kernel/PathAliasMenuLinkContentTest.php
index 046deb4..3732f8d 100644
--- a/core/modules/menu_link_content/tests/src/Kernel/PathAliasMenuLinkContentTest.php
+++ b/core/modules/menu_link_content/tests/src/Kernel/PathAliasMenuLinkContentTest.php
@@ -30,7 +30,7 @@ protected function setUp() {
 
     // Ensure that the weight of module_link_content is higher than system.
     // @see menu_link_content_install()
-    module_set_weight('menu_link_content', 1);
+    \Drupal::moduleHandler()->setWeight('menu_link_content', 1);
   }
 
   /**
diff --git a/core/modules/page_cache/tests/modules/page_cache_form_test.install b/core/modules/page_cache/tests/modules/page_cache_form_test.install
index 07f68ce..1210d3a 100644
--- a/core/modules/page_cache/tests/modules/page_cache_form_test.install
+++ b/core/modules/page_cache/tests/modules/page_cache_form_test.install
@@ -11,5 +11,5 @@
 function page_cache_form_test_install() {
   // Set an explicit module weight, to ensure that the form alter hook is
   // always called after page_cache_form_alter().
-  module_set_weight('page_cache_form_test', 10);
+  \Drupal::moduleHandler()->setWeight('page_cache_form_test', 10);
 }
diff --git a/core/modules/simpletest/src/Tests/KernelTestBaseTest.php b/core/modules/simpletest/src/Tests/KernelTestBaseTest.php
index 1e9e75d..97beafa 100644
--- a/core/modules/simpletest/src/Tests/KernelTestBaseTest.php
+++ b/core/modules/simpletest/src/Tests/KernelTestBaseTest.php
@@ -262,7 +262,7 @@ public function testEnableModulesFixedList() {
     $this->assertTrue(TRUE == $entity_manager->getDefinition('entity_test'));
 
     // Set the weight of a module; entity_test should still exist.
-    module_set_weight('field', -1);
+    \Drupal::moduleHandler()->setWeight('field', -1);
     $this->assertEqual($this->container->get('module_handler')->moduleExists('entity_test'), TRUE);
     $this->assertTrue(TRUE == $entity_manager->getDefinition('entity_test'));
 
diff --git a/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.install b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.install
index 4d992d4..55f1d7e 100644
--- a/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.install
+++ b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.install
@@ -10,5 +10,5 @@
  */
 function module_handler_test_multiple_install() {
   // Set weight of module.
-  module_set_weight('module_handler_test_multiple', 1);
+  \Drupal::moduleHandler()->setWeight('module_handler_test_multiple', 1);
 }
diff --git a/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple_child/module_handler_test_multiple_child.install b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple_child/module_handler_test_multiple_child.install
index c373c65..6aeeba3 100644
--- a/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple_child/module_handler_test_multiple_child.install
+++ b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple_child/module_handler_test_multiple_child.install
@@ -13,5 +13,5 @@
  */
 function module_handler_test_multiple_child_install() {
   // Set weight of module.
-  module_set_weight('module_handler_test_multiple_child', 1);
+  \Drupal::moduleHandler()->setWeight('module_handler_test_multiple_child', 1);
 }
diff --git a/core/modules/system/tests/modules/url_alter_test/url_alter_test.install b/core/modules/system/tests/modules/url_alter_test/url_alter_test.install
index 0237a9e..f318ef8 100644
--- a/core/modules/system/tests/modules/url_alter_test/url_alter_test.install
+++ b/core/modules/system/tests/modules/url_alter_test/url_alter_test.install
@@ -10,5 +10,5 @@
  */
 function url_alter_test_install() {
   // Set the weight of this module to one higher than forum.module.
-  module_set_weight('url_alter_test', 2);
+  \Drupal::moduleHandler()->setWeight('url_alter_test', 2);
 }
diff --git a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
index d7c2650..2e141d8 100644
--- a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
+++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
@@ -50,7 +50,7 @@ public function testModuleList() {
     $this->assertModuleList($module_list, 'After adding a module');
 
     // Try to mess with the module weights.
-    module_set_weight('ban', 20);
+    $this->moduleHandler()->setWeight('ban', 20);
 
     // Move ban to the end of the array.
     unset($module_list[array_search('ban', $module_list)]);
diff --git a/core/modules/views/views.install b/core/modules/views/views.install
index 21b1a50..c9a2fe3 100644
--- a/core/modules/views/views.install
+++ b/core/modules/views/views.install
@@ -12,7 +12,7 @@
  * Implements hook_install().
  */
 function views_install() {
-  module_set_weight('views', 10);
+  \Drupal::moduleHandler()->setWeight('views', 10);
 }
 
 /**
