diff --git a/core/modules/forum/forum.admin.inc b/core/modules/forum/forum.admin.inc
index e5e798f..7c52780 100644
--- a/core/modules/forum/forum.admin.inc
+++ b/core/modules/forum/forum.admin.inc
@@ -127,19 +127,22 @@ function forum_form_submit($form, &$form_state) {
 }
 
 /**
- * Returns HTML for a forum form.
+ * Prepares variables for forum form templates.
  *
- * By default this does not alter the appearance of a form at all, but is
- * provided as a convenience for themers.
+ * Default template: forum-form.html.twig.
  *
- * @param $variables
+ * @param array $variables
  *   An associative array containing:
  *   - form: A render element representing the form.
- *
- * @ingroup themeable
  */
-function theme_forum_form($variables) {
-  return drupal_render_children($variables['form']);
+function template_preprocess_forum_form(&$variables) {
+  // Prevent recursion loop by removing '#theme' and '#theme_wrappers' keys.
+  // See http://drupal.org/node/1920886.
+  foreach (array('#theme', '#theme_wrappers') as $theme_key) {
+    if (isset($variables['form'][$theme_key])) {
+      unset($variables['form'][$theme_key]);
+    }
+  }
 }
 
 /**
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index eb2c1ec..8741229 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -83,6 +83,7 @@ function forum_theme() {
     'forum_form' => array(
       'render element' => 'form',
       'file' => 'forum.admin.inc',
+      'template' => 'forum-form',
     ),
   );
 }
@@ -977,9 +978,11 @@ function forum_preprocess_block(&$variables) {
 }
 
 /**
- * Preprocesses variables for forums.tpl.php.
+ * Prepares variables for forum templates.
  *
- * @param $variables
+ * Default template: forums.html.twig.
+ *
+ * @param array $variables
  *   An array containing the following elements:
  *   - forums: An array of all forum objects to display for the given taxonomy
  *     term ID. If tid = 0 then all the top-level forums are displayed.
@@ -993,23 +996,32 @@ function forum_preprocess_block(&$variables) {
  *     - 3: Posts with the most comments first.
  *     - 4: Posts with the least comments first.
  *   - forum_per_page: The maximum number of topics to display per page.
- *
- * @see forums.tpl.php
  */
 function template_preprocess_forums(&$variables) {
   if ($variables['forums_defined'] = count($variables['forums']) || count($variables['parents'])) {
     if (!empty($variables['forums'])) {
-      $variables['forums'] = theme('forum_list', $variables);
+      $variables['forums'] = array(
+        '#theme' => 'forum_list',
+        '#forums' => $variables['forums'],
+        '#parents' => $variables['parents'],
+        '#tid' => $variables['tid'],
+      );
     }
     else {
-      $variables['forums'] = '';
+      $variables['forums'] = array();
     }
 
     if ($variables['tid'] && array_search($variables['tid'], config('forum.settings')->get('containers')) === FALSE) {
-      $variables['topics'] = theme('forum_topic_list', $variables);
+      $variables['topics'] = array(
+        '#theme' => 'forum_topic_list',
+        '#tid' => $variables['tid'],
+        '#topics' => $variables['topics'],
+        '#sortby' => $variables['sortby'],
+        '#forum_per_page' => $variables['forum_per_page'],
+      );
     }
     else {
-      $variables['topics'] = '';
+      $variables['topics'] = array();
     }
 
     // Provide separate template suggestions based on what's being output. Topic id is also accounted for.
@@ -1030,24 +1042,23 @@ function template_preprocess_forums(&$variables) {
 
   }
   else {
-    $variables['forums'] = '';
-    $variables['topics'] = '';
+    $variables['forums'] = array();
+    $variables['topics'] = array();
   }
 }
 
 /**
- * Preprocesses variables for forum-list.tpl.php.
+ * Prepares variables for forum list templates.
+ *
+ * Default template: forum-list.html.twig.
  *
- * @param $variables
+ * @param array $variables
  *   An array containing the following elements:
  *   - forums: An array of all forum objects to display for the given taxonomy
  *     term ID. If tid = 0 then all the top-level forums are displayed.
  *   - parents: An array of taxonomy term objects that are ancestors of the
  *     current term ID.
  *   - tid: Taxonomy term ID of the current forum.
- *
- * @see forum-list.tpl.php
- * @see theme_forum_list()
  */
 function template_preprocess_forum_list(&$variables) {
   global $user;
@@ -1078,23 +1089,36 @@ function template_preprocess_forum_list(&$variables) {
       $variables['forums'][$id]->old_topics = $forum->num_topics - $variables['forums'][$id]->new_topics;
     }
     $variables['forums'][$id]->last_reply = theme('forum_submitted', array('topic' => $forum->last_post));
+    // Cast num_posts and num_topics to strings to ensure the value can be
+    // printed in the template because Twig with strict variables off will not
+    // print int(0).
+    $variables['forums'][$id]->num_posts = (string) $variables['forums'][$id]->num_posts;
+    $variables['forums'][$id]->num_topics = (string) $variables['forums'][$id]->num_topics;
   }
-  // Give meaning to $tid for themers. $tid actually stands for term id.
-  $variables['forum_id'] = $variables['tid'];
+
+  $variables['pager'] = array(
+   '#theme' => 'pager',
+   '#tags' => NULL,
+  );
+
+  // Cast forum_id to a string to ensure the value can be
+  // printed in the template because Twig with strict variables off will not
+  // print int(0).
+  // Give meaning to $tid for themers. $tid actually stands for term ID.
+  $variables['forum_id'] = (string) $variables['tid'];
   unset($variables['tid']);
 }
 
 /**
- * Preprocesses variables for forum-topic-list.tpl.php.
+ * Prepares variables for forum topic list templates.
+ *
+ * Default template: forum-topic-list.html.twig.
  *
- * @param $variables
+ * @param array $variables
  *   An array containing the following elements:
  *   - tid: Taxonomy term ID of the current forum.
  *   - topics: An array of all the topics in the current forum.
  *   - forum_per_page: The maximum number of topics to display per page.
- *
- * @see forum-topic-list.tpl.php
- * @see theme_forum_topic_list()
  */
 function template_preprocess_forum_topic_list(&$variables) {
   global $forum_topic_list_header;
@@ -1111,7 +1135,14 @@ function template_preprocess_forum_topic_list(&$variables) {
   if (!empty($variables['topics'])) {
     $row = 0;
     foreach ($variables['topics'] as $id => $topic) {
-      $variables['topics'][$id]->icon = theme('forum_icon', array('new_posts' => $topic->new, 'num_posts' => $topic->comment_count, 'comment_mode' => $topic->comment_mode, 'sticky' => $topic->sticky, 'first_new' => $topic->first_new));
+      $variables['topics'][$id]->icon = array(
+        '#theme' => 'forum_icon',
+        '#new_posts' => $topic->new,
+        '#num_posts' => $topic->comment_count,
+        '#comment_mode' => $topic->comment_mode,
+        '#sticky' => $topic->sticky,
+        '#first_new' => $topic->first_new,
+      );
       $variables['topics'][$id]->zebra = $row % 2 == 0 ? 'odd' : 'even';
       $row++;
 
@@ -1148,13 +1179,15 @@ function template_preprocess_forum_topic_list(&$variables) {
   $variables['topic_id'] = $variables['tid'];
   unset($variables['tid']);
 
-  $variables['pager'] = theme('pager');
+  $variables['pager'] = array(
+    '#theme' => 'pager',
+  );
 }
 
 /**
- * Preprocesses variables for forum-icon.tpl.php.
+ * Prepares variables for forum icon templates.
  *
- * @param $variables
+ * @param array $variables
  *   An array containing the following elements:
  *   - new_posts: Indicates whether or not the topic contains new posts.
  *   - num_posts: The total number of posts in all topics.
@@ -1162,9 +1195,6 @@ function template_preprocess_forum_topic_list(&$variables) {
  *     or hidden.
  *   - sticky: Indicates whether the topic is sticky.
  *   - first_new: Indicates whether this is the first topic with new posts.
- *
- * @see forum-icon.tpl.php
- * @see theme_forum_icon()
  */
 function template_preprocess_forum_icon(&$variables) {
   $variables['hot_threshold'] = config('forum.settings')->get('topics.hot_threshold');
@@ -1189,17 +1219,16 @@ function template_preprocess_forum_icon(&$variables) {
 }
 
 /**
- * Preprocesses variables for forum-submitted.tpl.php.
+ * Prepares variables for forum submission information templates.
  *
  * The submission information will be displayed in the forum list and topic
  * list.
  *
- * @param $variables
+ * Default template: forum-submitted.html.twig.
+ *
+ * @param array $variables
  *   An array containing the following elements:
  *   - topic: The topic object.
- *
- * @see forum-submitted.tpl.php
- * @see theme_forum_submitted()
  */
 function template_preprocess_forum_submitted(&$variables) {
   $variables['author'] = isset($variables['topic']->uid) ? theme('username', array('account' => $variables['topic'])) : '';
diff --git a/core/modules/forum/templates/forum-form.html.twig b/core/modules/forum/templates/forum-form.html.twig
new file mode 100644
index 0000000..614d0eb
--- /dev/null
+++ b/core/modules/forum/templates/forum-form.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @see
+ * Default theme implementation for a forum form.
+ *
+ * By default this does not alter the appearance of a form at all, but is
+ * provided as a convenience for themers.
+ *
+ * Available variables:
+ * - form: The complete form. Use {{ form }} to print the entire form, or print
+ *   a subset such as {{ form.title }}. Use {% hide(form.description) %} to
+ *   temporarily suppress the printing of a given element.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_forum_form()
+ *
+ * @ingroup themeable
+ */
+#}
+{{ form }}
diff --git a/core/modules/forum/templates/forum-icon.html.twig b/core/modules/forum/templates/forum-icon.html.twig
new file mode 100644
index 0000000..25d7fe6
--- /dev/null
+++ b/core/modules/forum/templates/forum-icon.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display an appropriate icon for a forum post.
+ *
+ * Available variables:
+ * - new_posts: Indicates whether or not the topic contains new posts.
+ * - icon_class: The icon to display. May be one of 'hot', 'hot-new', 'new',
+ *   'default', 'closed', or 'sticky'.
+ * - icon_title: Text alternative for the forum icon.
+ * - first_new: Indicates whether this is the first topic with new posts.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_forum_icon()
+ *
+ * @ingroup themeable
+ */
+#}
+<div class="icon topic-status-{{ icon_class }}" title="{{ icon_title }}">
+  {% if first_new %}<a id="new"></a>{% endif %}
+  <span class="element-invisible">{{ icon_title }}</span>
+</div>
diff --git a/core/modules/forum/templates/forum-icon.tpl.php b/core/modules/forum/templates/forum-icon.tpl.php
deleted file mode 100644
index 8b70eb3..0000000
--- a/core/modules/forum/templates/forum-icon.tpl.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * @file
- * Displays an appropriate icon for a forum post.
- *
- * Available variables:
- * - $new_posts: Indicates whether or not the topic contains new posts.
- * - $icon_class: The icon to display. May be one of 'hot', 'hot-new', 'new',
- *   'default', 'closed', or 'sticky'.
- * - $first_new: Indicates whether this is the first topic with new posts.
- *
- * @see template_preprocess_forum_icon()
- * @see theme_forum_icon()
- *
- * @ingroup themeable
- */
-?>
-<div class="icon topic-status-<?php print $icon_class ?>" title="<?php print $icon_title ?>">
-<?php if ($first_new): ?>
-  <a id="new"></a>
-<?php endif; ?>
-
-  <span class="element-invisible"><?php print $icon_title ?></span>
-
-</div>
diff --git a/core/modules/forum/templates/forum-list.html.twig b/core/modules/forum/templates/forum-list.html.twig
new file mode 100644
index 0000000..361d127
--- /dev/null
+++ b/core/modules/forum/templates/forum-list.html.twig
@@ -0,0 +1,84 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display a list of forums and containers.
+ *
+ * Available variables:
+ * - forums: A collection of forums and containers to display. It is keyed to
+ *   the numeric IDs of all child forums and containers. Each forum in forums
+ *   contains:
+ *   - is_container: A flag indicating if the forum can contain other
+ *     forums. Otherwise, the forum can only contain topics.
+ *   - depth: How deep the forum is in the current hierarchy.
+ *   - zebra: 'even' or 'odd', used for row class.
+ *   - icon_class: 'default' or 'new', used for forum icon class.
+ *   - icon_title: Text alternative for the forum icon.
+ *   - name: The name of the forum.
+ *   - link: The URL to link to this forum.
+ *   - description: The description of this forum.
+ *   - new_topics: A flag indicating if the forum contains unread posts.
+ *   - new_url: A URL to the forum's unread posts.
+ *   - new_text: Text for the above URL, which tells how many new posts.
+ *   - old_topics: A count of posts that have already been read.
+ *   - num_posts: The total number of posts in the forum.
+ *   - last_reply: Text representing the last time a forum was posted or
+ *     commented in.
+ * - forum_id: Forum ID for the current forum. Parent to all items within the
+ *   forums array.
+ *
+ * @todo Replace this with existing theme functions:
+ *   http://drupal.org/node/1812684
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_forum_list()
+ *
+ * @ingroup themeable
+ */
+#}
+<table id="forum-{{ forum_id }}">
+  <thead>
+    <tr>
+      <th>{{ 'Forum'|t }}</th>
+      <th>{{ 'Topics'|t }}</th>
+      <th>{{ 'Posts'|t }}</th>
+      <th>{{ 'Last post'|t }}</th>
+    </tr>
+  </thead>
+  <tbody>
+  {% for child_id, forum in forums %}
+    <tr id="forum-list-{{ child_id }}" class="{{ forum.zebra }}">
+      <td {% if forum.is_container == true -%}
+        colspan="4" class="container"
+      {%- else -%}
+        class="forum"
+      {%- endif -%}>
+        {#
+          Enclose the contents of this cell with X divs, where X is the
+          depth this forum resides at. This will allow us to use CSS
+          left-margin for indenting.
+        #}
+        {% for i in 1..forum.depth if forum.depth > 0 %}<div class="indent">{% endfor %}
+          <div class="icon forum-status-{{ forum.icon_class }}" title="{{ forum.icon_title }}">
+            <span class="element-invisible">{{ forum.icon_title }}</span>
+          </div>
+          <div class="name"><a href="{{ forum.link }}">{{ forum.label }}</a></div>
+          {% if forum.description %}
+            <div class="description">{{ forum.description }}</div>
+          {% endif %}
+        {% for i in 1..forum.depth if forum.depth > 0 %}</div>{% endfor %}
+      </td>
+      {% if forum.is_container == false %}
+        <td class="topics">
+          {{ forum.num_topics }}
+          {% if forum.new_topics == true %}
+            <br />
+            <a href="{{ forum.new_url }}">{{ forum.new_text }}</a>
+          {% endif %}
+        </td>
+        <td class="posts">{{ forum.num_posts }}</td>
+        <td class="last-reply">{{ forum.last_reply }}</td>
+      {% endif %}
+    </tr>
+  {% endfor %}
+  </tbody>
+</table>
diff --git a/core/modules/forum/templates/forum-list.tpl.php b/core/modules/forum/templates/forum-list.tpl.php
deleted file mode 100644
index b169493..0000000
--- a/core/modules/forum/templates/forum-list.tpl.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-
-/**
- * @file
- * Displays a list of forums and containers.
- *
- * Available variables:
- * - $forums: An array of forums and containers to display. It is keyed to the
- *   numeric IDs of all child forums and containers. Each $forum in $forums
- *   contains:
- *   - $forum->is_container: TRUE if the forum can contain other forums. FALSE
- *     if the forum can contain only topics.
- *   - $forum->depth: How deep the forum is in the current hierarchy.
- *   - $forum->zebra: 'even' or 'odd' string used for row class.
- *   - $forum->icon_class: 'default' or 'new' string used for forum icon class.
- *   - $forum->icon_title: Text alternative for the forum icon.
- *   - $forum->name: The name of the forum.
- *   - $forum->link: The URL to link to this forum.
- *   - $forum->description: The description of this forum.
- *   - $forum->new_topics: TRUE if the forum contains unread posts.
- *   - $forum->new_url: A URL to the forum's unread posts.
- *   - $forum->new_text: Text for the above URL, which tells how many new posts.
- *   - $forum->old_topics: A count of posts that have already been read.
- *   - $forum->num_posts: The total number of posts in the forum.
- *   - $forum->last_reply: Text representing the last time a forum was posted or
- *     commented in.
- * - $forum_id: Forum ID for the current forum. Parent to all items within the
- *   $forums array.
- *
- * @see template_preprocess_forum_list()
- * @see theme_forum_list()
- *
- * @ingroup themeable
- */
-?>
-<table id="forum-<?php print $forum_id; ?>">
-  <thead>
-    <tr>
-      <th><?php print t('Forum'); ?></th>
-      <th><?php print t('Topics');?></th>
-      <th><?php print t('Posts'); ?></th>
-      <th><?php print t('Last post'); ?></th>
-    </tr>
-  </thead>
-  <tbody>
-  <?php foreach ($forums as $child_id => $forum): ?>
-    <tr id="forum-list-<?php print $child_id; ?>" class="<?php print $forum->zebra; ?>">
-      <td <?php print $forum->is_container ? 'colspan="4" class="container"' : 'class="forum"'; ?>>
-        <?php /* Enclose the contents of this cell with X divs, where X is the
-               * depth this forum resides at. This will allow us to use CSS
-               * left-margin for indenting.
-               */ ?>
-        <?php print str_repeat('<div class="indent">', $forum->depth); ?>
-          <div class="icon forum-status-<?php print $forum->icon_class; ?>" title="<?php print $forum->icon_title; ?>">
-            <span class="element-invisible"><?php print $forum->icon_title; ?></span>
-          </div>
-          <div class="name"><a href="<?php print $forum->link; ?>"><?php print $forum->label(); ?></a></div>
-          <?php if ($forum->description): ?>
-            <div class="description"><?php print $forum->description; ?></div>
-          <?php endif; ?>
-        <?php print str_repeat('</div>', $forum->depth); ?>
-      </td>
-      <?php if (!$forum->is_container): ?>
-        <td class="topics">
-          <?php print $forum->num_topics ?>
-          <?php if ($forum->new_topics): ?>
-            <br />
-            <a href="<?php print $forum->new_url; ?>"><?php print $forum->new_text; ?></a>
-          <?php endif; ?>
-        </td>
-        <td class="posts"><?php print $forum->num_posts ?></td>
-        <td class="last-reply"><?php print $forum->last_reply ?></td>
-      <?php endif; ?>
-    </tr>
-  <?php endforeach; ?>
-  </tbody>
-</table>
diff --git a/core/modules/forum/templates/forum-submitted.html.twig b/core/modules/forum/templates/forum-submitted.html.twig
new file mode 100644
index 0000000..ad059dc
--- /dev/null
+++ b/core/modules/forum/templates/forum-submitted.html.twig
@@ -0,0 +1,24 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a forum post submission string.
+ *
+ * The submission string indicates when and by whom a topic was submitted.
+ *
+ * Available variables:
+ * - author: The author of the post.
+ * - time: How long ago the post was created.
+ * - topic: An object with the raw data of the post. Potentially unsafe. Be
+ *   sure to clean this data before printing.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_forum_submitted()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if time %}
+  <span class="submitted">{{ 'By !author @time ago'|t({'@time': time, '!author': author}) }}</span>
+{% else %}
+  {{ 'n/a'|t }}
+{% endif %}
diff --git a/core/modules/forum/templates/forum-submitted.tpl.php b/core/modules/forum/templates/forum-submitted.tpl.php
deleted file mode 100644
index 18fea8f..0000000
--- a/core/modules/forum/templates/forum-submitted.tpl.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/**
- * @file
- * Formats a forum post submission string.
- *
- * The submission string indicates when and by whom a topic was submitted.
- *
- * Available variables:
- * - $author: The author of the post.
- * - $time: How long ago the post was created.
- * - $topic: An object with the raw data of the post. Potentially unsafe. Be
- *   sure to clean this data before printing.
- *
- * @see template_preprocess_forum_submitted()
- * @see theme_forum_submitted()
- *
- * @ingroup themeable
- */
-?>
-<?php if ($time): ?>
-  <span class="submitted">
-  <?php print t('By !author @time ago', array(
-    '@time' => $time,
-    '!author' => $author,
-    )); ?>
-  </span>
-<?php else: ?>
-  <?php print t('n/a'); ?>
-<?php endif; ?>
diff --git a/core/modules/forum/templates/forum-topic-list.html.twig b/core/modules/forum/templates/forum-topic-list.html.twig
new file mode 100644
index 0000000..32727ee
--- /dev/null
+++ b/core/modules/forum/templates/forum-topic-list.html.twig
@@ -0,0 +1,69 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display a list of forum topics.
+ *
+ * Available variables:
+ * - header: The table header. This is pre-generated with click-sorting
+ *   information. If you need to change this, see
+ *   template_preprocess_forum_topic_list().
+ * - pager: The pager to display beneath the table.
+ * - topics: A collection of topics to be displayed. Each topic in topics
+ *   contains:
+ *   - icon: The icon to display.
+ *   - moved: A flag to indicate whether the topic has been moved to another
+ *     forum.
+ *   - title: The title of the topic. Safe to output.
+ *   - message: If the topic has been moved, this contains an explanation and a
+ *     link.
+ *   - zebra: 'even' or 'odd', used for row class.
+ *   - comment_count: The number of replies on this topic.
+ *   - new_replies: A flag to indicate whether there are unread comments.
+ *   - new_url: If there are unread replies, this is a link to them.
+ *   - new_text: Text containing the translated, properly pluralized count.
+ *   - created: Text representing when the topic was posted. Safe to output.
+ *   - last_reply: Text representing when the topic was last replied to.
+ *   - timestamp: The raw timestamp this topic was posted.
+ * - topic_id: Numeric ID for the current forum topic.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_forum_topic_list()
+ *
+ * @ingroup themeable
+ */
+#}
+<table id="forum-topic-{{ topic_id }}">
+  <thead>
+    <tr>{{ header }}</tr>
+  </thead>
+  <tbody>
+  {% for topic in topics %}
+    <tr class="{{ topic.zebra }}">
+      <td class="topic">
+        {{ topic.icon }}
+        <div class="title">
+          <div>
+            {{ topic.title }}
+          </div>
+          <div>
+            {{ topic.created }}
+          </div>
+        </div>
+      </td>
+    {% if topic.moved %}
+      <td colspan="3">{{ topic.message }}</td>
+    {% else %}
+      <td class="replies">
+        {{ topic.comment_count }}
+        {% if topic.new_replies %}
+          <br />
+          <a href="{{ topic.new_url }}">{{ topic.new_text }}</a>
+        {% endif %}
+      </td>
+      <td class="last-reply">{{ topic.last_reply }}</td>
+    {% endif %}
+    </tr>
+  {% endfor %}
+  </tbody>
+</table>
+{{ pager }}
diff --git a/core/modules/forum/templates/forum-topic-list.tpl.php b/core/modules/forum/templates/forum-topic-list.tpl.php
deleted file mode 100644
index 5130ed6..0000000
--- a/core/modules/forum/templates/forum-topic-list.tpl.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-/**
- * @file
- * Displays a list of forum topics.
- *
- * Available variables:
- * - $header: The table header. This is pre-generated with click-sorting
- *   information. If you need to change this, see
- *   template_preprocess_forum_topic_list().
- * - $pager: The pager to display beneath the table.
- * - $topics: An array of topics to be displayed. Each $topic in $topics
- *   contains:
- *   - $topic->icon: The icon to display.
- *   - $topic->moved: A flag to indicate whether the topic has been moved to
- *     another forum.
- *   - $topic->title: The title of the topic. Safe to output.
- *   - $topic->message: If the topic has been moved, this contains an
- *     explanation and a link.
- *   - $topic->zebra: 'even' or 'odd' string used for row class.
- *   - $topic->comment_count: The number of replies on this topic.
- *   - $topic->new_replies: A flag to indicate whether there are unread
- *     comments.
- *   - $topic->new_url: If there are unread replies, this is a link to them.
- *   - $topic->new_text: Text containing the translated, properly pluralized
- *     count.
- *   - $topic->created: A string representing when the topic was posted. Safe
- *     to output.
- *   - $topic->last_reply: An outputtable string representing when the topic was
- *     last replied to.
- *   - $topic->timestamp: The raw timestamp this topic was posted.
- * - $topic_id: Numeric ID for the current forum topic.
- *
- * @see template_preprocess_forum_topic_list()
- * @see theme_forum_topic_list()
- *
- * @ingroup themeable
- */
-?>
-<table id="forum-topic-<?php print $topic_id; ?>">
-  <thead>
-    <tr><?php print $header; ?></tr>
-  </thead>
-  <tbody>
-  <?php foreach ($topics as $topic): ?>
-    <tr class="<?php print $topic->zebra;?>">
-      <td class="topic">
-        <?php print $topic->icon; ?>
-        <div class="title">
-          <div>
-            <?php print $topic->title; ?>
-          </div>
-          <div>
-            <?php print $topic->created; ?>
-          </div>
-        </div>
-      </td>
-    <?php if ($topic->moved): ?>
-      <td colspan="3"><?php print $topic->message; ?></td>
-    <?php else: ?>
-      <td class="replies">
-        <?php print $topic->comment_count; ?>
-        <?php if ($topic->new_replies): ?>
-          <br />
-          <a href="<?php print $topic->new_url; ?>"><?php print $topic->new_text; ?></a>
-        <?php endif; ?>
-      </td>
-      <td class="last-reply"><?php print $topic->last_reply; ?></td>
-    <?php endif; ?>
-    </tr>
-  <?php endforeach; ?>
-  </tbody>
-</table>
-<?php print $pager; ?>
diff --git a/core/modules/forum/templates/forums.html.twig b/core/modules/forum/templates/forums.html.twig
new file mode 100644
index 0000000..59fff7d
--- /dev/null
+++ b/core/modules/forum/templates/forums.html.twig
@@ -0,0 +1,24 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display a forum.
+ *
+ * May contain forum containers as well as forum topics.
+ *
+ * Available variables:
+ * - forums: The forums to display (as processed by forum-list.html.twig).
+ * - topics: The topics to display (as processed by forum-topic-list.html.twig).
+ * - forums_defined: A flag to indicate that the forums are configured.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_forums()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if forums_defined %}
+  <div id="forum">
+    {{ forums }}
+    {{ topics }}
+  </div>
+{% endif %}
diff --git a/core/modules/forum/templates/forums.tpl.php b/core/modules/forum/templates/forums.tpl.php
deleted file mode 100644
index 6a0e02e..0000000
--- a/core/modules/forum/templates/forums.tpl.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Displays a forum.
- *
- * May contain forum containers as well as forum topics.
- *
- * Available variables:
- * - $forums: The forums to display (as processed by forum-list.tpl.php).
- * - $topics: The topics to display (as processed by forum-topic-list.tpl.php).
- * - $forums_defined: A flag to indicate that the forums are configured.
- *
- * @see template_preprocess_forums()
- *
- * @ingroup themeable
- */
-?>
-<?php if ($forums_defined): ?>
-<div id="forum">
-  <?php print $forums; ?>
-  <?php print $topics; ?>
-</div>
-<?php endif; ?>
