diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 11b72a5..27da4b2 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -277,83 +277,49 @@ function theme_system_modules_details($variables) {
 }
 
 /**
- * Returns HTML for a table of currently disabled modules.
+ * Prepares variables for the module uninstall template.
  *
  * @param $variables
  *   An associative array containing:
- *   - form: A render element representing the form.
+ *   - form: A render element representing the form. Child elements of the form
+ *     are individual modules. Each module is an associative array containing
+ *     the following elements:
+ *     - #module_name: The name of the module as a string.
+ *     - name: The name of the module in a renderable array.
+ *     - description: A description of the module.
+ *     - #required_by: (optional) A list of modules that require the module.
+ *     - #validation_reasons: (optional) Additional reasons why the module
+ *       cannot be disabled.
+ *     - #attributes: A list of attributes for the module wrapper.
  *
  * @ingroup themeable
  */
-function theme_system_modules_uninstall($variables) {
+function template_preprocess_system_modules_uninstall(&$variables) {
   $form = $variables['form'];
+  $variables['modules'] = [];
 
-  // No theming for the confirm form.
-  if (isset($form['confirm'])) {
-    return drupal_render($form);
-  }
+  $variables['empty'] = t('No modules are available to uninstall.');
 
-  // Table headers.
-  $header = array(t('Uninstall'),
-    t('Name'),
-    t('Description'),
-  );
+  // Iterate through all the modules, which are children of this element.
+  foreach (Element::children($form['modules']) as $key) {
+    $module = $form['modules'][$key];
+    $module['plain_name'] = $module['#module_name'];
+    $module['checkbox'] = $form['uninstall'][$key];
+    $module['checkbox_id'] = $form['uninstall'][$key]['#id'];
 
-  // Display table.
-  $rows = array();
-  foreach (Element::children($form['modules']) as $module) {
-    $disabled_header = '';
-    $disabled_reasons = '';
-    // Add the modules requiring the module in question as a validation reason.
-    if (!empty($form['modules'][$module]['#required_by'])) {
-      $form['modules'][$module]['#validation_reasons'][] = \Drupal::translation()->translate('Required by: @modules', array('@modules' => implode(', ',$form['modules'][$module]['#required_by'])));
+    if (!empty($module['#validation_reasons'])) {
+      $module['validation_reasons'] = $module['#validation_reasons'];
+      $module['reasons_count'] = count($module['validation_reasons']);
+    } else {
+      $module['reasons_count'] = 0;
     }
-    if (!empty($form['modules'][$module]['#validation_reasons'])) {
-      $disabled_reasons = [
-        '#theme' => 'item_list',
-        '#items' => $form['modules'][$module]['#validation_reasons'],
-      ];
-      $disabled_reasons = drupal_render($disabled_reasons);
-      $disabled_header = \Drupal::translation()->formatPlural(count($form['modules'][$module]['#validation_reasons']),
-        'The following reason prevents @module from being uninstalled:',
-        'The following reasons prevents @module from being uninstalled:',
-        array('@module' => $form['modules'][$module]['#module_name']));
+    if (!empty($module['#required_by'])) {
+      $module['required_by'] = $module['#required_by'];
+      $module['reasons_count'] = $module['reasons_count'] + 1;
     }
-    $rows[] = array(
-      array('data' => drupal_render($form['uninstall'][$module]), 'align' => 'center'),
-      array(
-        'data' => array(
-          '#type' => 'inline_template',
-          '#template' => '<label for="{{ module_id }}" class="module-name table-filter-text-source">{{ module_name }}</label>',
-          '#context' => array('module_id' => $form['uninstall'][$module]['#id'], 'module_name' => drupal_render($form['modules'][$module]['name'])),
-        )
-      ),
-      array(
-        'data' => array(
-          '#type' => 'inline_template',
-          '#template' => '<span class="text module-description">{{ module_description }}</span>{% if disabled_header is not empty %}<div class="admin-requirements">{{ disabled_header }}{{ disabled_reasons }}</div>{% endif %}',
-          '#context' => array(
-            'module_description' => drupal_render($form['modules'][$module]['description']),
-            'disabled_header' => $disabled_header,
-            'disabled_reasons' => $disabled_reasons,
-          ),
-        ),
-        'class' => array('description'),
-      ),
-    );
+    $module['attributes'] = new Attribute($module['#attributes']);
+    $variables['modules'][] = $module;
   }
-
-  $table = array(
-    '#type' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('No modules are available to uninstall.'),
-  );
-  $output = drupal_render($form['filters']);
-  $output .= drupal_render($table);
-  $output .= drupal_render_children($form);
-
-  return $output;
 }
 
 /**
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index a8477d3..80af03d 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -191,7 +191,6 @@ function system_theme() {
     'system_modules_uninstall' => array(
       'render element' => 'form',
       'file' => 'system.admin.inc',
-      'function' => 'theme_system_modules_uninstall',
     ),
     'status_report' => array(
       'variables' => array('requirements' => NULL),
diff --git a/core/modules/system/templates/system-modules-uninstall.html.twig b/core/modules/system/templates/system-modules-uninstall.html.twig
new file mode 100644
index 0000000..a56a113
--- /dev/null
+++ b/core/modules/system/templates/system-modules-uninstall.html.twig
@@ -0,0 +1,80 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the modules uninstall page.
+ *
+ * Available variables:
+ * - form: The modules uninstall form.
+ * - modules: Contains multiple module instances. Each module contains:
+ *   - attributes: Attributes on the row.
+ *   - plain_name: The plain-text name of the module.
+ *   - checkbox: A checkbox for uninstalling the module.
+ *   - checkbox_id: A unique id for interacting with the checkbox element.
+ *   - name: The human-readable name of the module.
+ *   - description: The description of the module.
+ *   - disabled_reasons: (optional) A list of reasons why this module cannot be
+ *     uninstalled.
+ *
+ *  @see template_preprocess_system_modules_uninstall()
+ *
+ * @ingroup themeable
+ */
+#}
+
+{{ form.filters }}
+
+<table class="system-modules-uninstall">
+  <thead>
+    <tr>
+      <th>
+        {{ 'Uninstall'|t }}
+      </th>
+      <th>
+        {{ 'Name'|t }}
+      </th>
+      <th>
+        {{ 'Description'|t }}
+      </th>
+    </tr>
+  </thead>
+  <tbody>
+    {% for module in modules %}
+      {% set zebra = cycle(['odd', 'even'], loop.index0) %}<tr{{ module.attributes.addClass(zebra) }}>
+        <td align="center">
+          {{ module.checkbox }}
+        </td>
+        <td>
+          <label for="{{ module.checkbox_id }}" class="module-name table-filter-text-source">{{ module.name }}</label>
+        </td>
+        <td class="description">
+          <span class="text module-description">{{ module.description }}</span>
+          {% if module.reasons_count > 0 %}
+            <div class="admin-requirements">
+              {% trans %}
+                The following reason prevents {{ module.plain_name }} from being uninstalled:
+              {% plural module.reasons_count %}
+                The following reasons prevent {{ module.plain_name }} from being uninstalled:
+              {% endtrans %}
+              <div class="item-list">
+                <ul>
+                  {% for reason in module.validation_reasons %}
+                    <li>{{ reason }}</li>
+                  {% endfor %}
+                  {% if module.required_by %}
+                    <li>{{ 'Required by:'|t }} {{ module.required_by|safe_join(', ') }}</li>
+                  {% endif %}
+                </ul>
+              </div>
+            </div>
+          {% endif %}
+        </td>
+      </tr>
+    {% else %}
+      <tr>
+        <td colspan="3">{{ empty }}</td>
+      </tr>
+    {% endfor %}
+  </tbody>
+</table>
+
+{{ form|without('filters', 'modules', 'uninstall') }}
