diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc
index 680f9a8..e1f0b56 100644
--- a/core/modules/search/search.pages.inc
+++ b/core/modules/search/search.pages.inc
@@ -72,15 +72,15 @@ function search_view($module = NULL, $keys = '') {
 }
 
 /**
- * Prepocesses the variables for search-results.tpl.php.
+ * Prepares variables for search results templates.
  *
- * @param $variables
+ * Default template: search-results.html.twig.
+ *
+ * @param (array) $variables
  *   An array with the following elements:
  *   - results: Search results array.
  *   - module: Module the search results came from (module implementing
  *     hook_search_info()).
- *
- * @see search-results.tpl.php
  */
 function template_preprocess_search_results(&$variables) {
   $variables['search_results'] = '';
@@ -88,22 +88,38 @@ function template_preprocess_search_results(&$variables) {
     $variables['module'] = check_plain($variables['module']);
   }
   foreach ($variables['results'] as $result) {
-    $variables['search_results'] .= theme('search_result', array('result' => $result, 'module' => $variables['module']));
+    $variables['search_results'][] = array(
+      '#theme' => 'search_result',
+      '#result' => $result,
+      '#module' => $variables['module'],
+    );
   }
-  $variables['pager'] = theme('pager', array('tags' => NULL));
+  $variables['pager'] = array(
+    '#theme' => 'pager',
+    '#tags' => NULL,
+  );
+  // @todo Revisit where this help text is added, see also
+  //   http://drupal.org/node/1918856.
+  $variables['help'] = search_help('search#noresults', drupal_help_arg());
   $variables['theme_hook_suggestions'][] = 'search_results__' . $variables['module'];
 }
 
 /**
- * Preprocesses the variables for search-result.tpl.php.
+ * Prepares variables for individual search result templates.
  *
- * @param $variables
+ * Default template: search-result.html.twig
+ *
+ * @param (array) $variables
  *   An array with the following elements:
- *   - result: Search results array.
+ *   - result: Individual search result.
  *   - module: Module the search results came from (module implementing
  *     hook_search_info()).
- *
- * @see search-result.tpl.php
+ *   - title_prefix: Additional output populated by modules, intended to be
+ *     displayed in front of the main title tag that appears in the template.
+ *   - title_suffix: Additional output populated by modules, intended to be
+ *     displayed after the main title tag that appears in the template.
+ *   - title_attributes: HTML attributes for the title.
+ *   - content_attributes: HTML attributes for the content.
  */
 function template_preprocess_search_result(&$variables) {
   $language_interface = language(LANGUAGE_TYPE_INTERFACE);
diff --git a/core/modules/search/templates/search-result.html.twig b/core/modules/search/templates/search-result.html.twig
new file mode 100644
index 0000000..41b094b
--- /dev/null
+++ b/core/modules/search/templates/search-result.html.twig
@@ -0,0 +1,77 @@
+{#
+/**
+ * @file
+ * Default theme implementation for displaying a single search result.
+ *
+ * This template renders a single search result and is collected into
+ * search-results.html.twig. This and the parent template are
+ * dependent to one another sharing the markup for ordered lists.
+ *
+ * Available variables:
+ * - url: URL of the result.
+ * - title: Title of the result.
+ * - snippet: A small preview of the result. Does not apply to user searches.
+ * - info: String of all the meta information ready for print. Does not apply
+ *   to user searches.
+ * - module: The machine-readable name of the module (tab) being searched, such
+ *   as "node" or "user".
+ * - title_prefix: Additional output populated by modules, intended to be
+ *   displayed in front of the main title tag that
+ *   appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ *   displayed after the main title tag that appears in the template.
+ * - info_split: Contains same data as info, but split into separate parts.
+ *   - info_split.type: Node type (or item type string supplied by module).
+ *   - info_split.user: Author of the node linked to users profile. Depends
+ *     on permission.
+ *   - info_split.date: Last update of the node. Short formatted.
+ *   - info_split.comment: Number of comments output as "% comments", %
+ *     being the count. (Depends on comment.module).
+ * @todo The info variable needs to be made drillable and each of these sub
+ *   items should instead be within info and renamed info.foo, info.bar, etc.
+ *
+ * Other variables:
+ * - title_attributes: HTML attributes for the title.
+ * - content_attributes: HTML attributes for the content.
+ *
+ * Since info_split is keyed, a direct print of the item is possible.
+ * This array does not apply to user searches so it is recommended to check
+ * for its existence before printing. The default keys of 'type', 'user' and
+ * 'date' always exist for node searches. Modules may provide other data.
+ * @code
+ *   {% if (info_split.comment) %}
+ *     <span class="info-comment">
+ *       {{ info_split.comment }}
+ *     </span>
+ *   {% endif %}
+ * @endcode
+ *
+ * To check for all available data within info_split, use the code below.
+ * @code
+ *   <pre>
+ *     {{ dump(info_split) }}
+ *   </pre>
+ * @endcode
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_search_result()
+ * @see template_process()
+ *
+ * @ingroup themeable
+ */
+#}
+<li {{ attributes }}>
+  {{ title_prefix }}
+  <h3 class="title"{{ title_attributes }}>
+    <a href="{{ url }}">{{ title }}</a>
+  </h3>
+  {{ title_suffix }}
+  <div class="search-snippet-info">
+    {% if snippet %}
+      <p class="search-snippet"{{ content_attributes }}>{{ snippet }}</p>
+    {% endif %}
+    {% if info %}
+      <p class="search-info">{{ info }}</p>
+    {% endif %}
+  </div>
+</li>
diff --git a/core/modules/search/templates/search-result.tpl.php b/core/modules/search/templates/search-result.tpl.php
deleted file mode 100644
index 850797b..0000000
--- a/core/modules/search/templates/search-result.tpl.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for displaying a single search result.
- *
- * This template renders a single search result and is collected into
- * search-results.tpl.php. This and the parent template are dependent on one
- * another sharing the markup for definition lists.
- *
- * Available variables:
- * - $url: URL of the result.
- * - $title: Title of the result.
- * - $snippet: A small preview of the result. Does not apply to user searches.
- * - $info: String of all the meta information ready for print. Does not apply
- *   to user searches.
- * - $info_split: Contains same data as $info, split into a keyed array.
- * - $module: The machine-readable name of the module (tab) being searched,
- *   such as "node" or "user".
- * - $title_prefix (array): An array containing additional output populated by
- *   modules, intended to be displayed in front of the main title tag that
- *   appears in the template.
- * - $title_suffix (array): An array containing additional output populated by
- *   modules, intended to be displayed after the main title tag that appears in
- *   the template.
- *
- * Default keys within $info_split:
- * - $info_split['type']: Node type (or item type string supplied by module).
- * - $info_split['user']: Author of the node linked to users profile. Depends
- *   on permission.
- * - $info_split['date']: Last update of the node. Short formatted.
- * - $info_split['comment']: Number of comments output as "% comments", %
- *   being the count. Depends on the Comment module.
- *
- * Other variables:
- * - $title_attributes: Array of HTML attributes for the title. It is
- *   flattened into a string within the variable $title_attributes.
- * - $content_attributes: Array of HTML attributes for the content. It is
- *   flattened into a string within the variable $content_attributes.
- *
- * Since $info_split is keyed, a direct print of the item is possible.
- * This array does not apply to user searches so it is recommended to check
- * for its existence before printing. The default keys of 'type', 'user' and
- * 'date' always exist for node searches. Modules may provide other data.
- * @code
- *   <?php if (isset($info_split['comment'])): ?>
- *     <span class="info-comment">
- *       <?php print $info_split['comment']; ?>
- *     </span>
- *   <?php endif; ?>
- * @endcode
- *
- * To check for all available data within $info_split, use the code below.
- * @code
- *   <?php print '<pre>'. check_plain(print_r($info_split, 1)) .'</pre>'; ?>
- * @endcode
- *
- * @see template_preprocess()
- * @see template_preprocess_search_result()
- * @see template_process()
- *
- * @ingroup themeable
- */
-?>
-<li <?php print $attributes; ?>>
-  <?php print render($title_prefix); ?>
-  <h3 class="title"<?php print $title_attributes; ?>>
-    <a href="<?php print $url; ?>"><?php print $title; ?></a>
-  </h3>
-  <?php print render($title_suffix); ?>
-  <div class="search-snippet-info">
-    <?php if ($snippet): ?>
-      <p class="search-snippet"<?php print $content_attributes; ?>><?php print $snippet; ?></p>
-    <?php endif; ?>
-    <?php if ($info): ?>
-      <p class="search-info"><?php print $info; ?></p>
-    <?php endif; ?>
-  </div>
-</li>
diff --git a/core/modules/search/templates/search-results.html.twig b/core/modules/search/templates/search-results.html.twig
new file mode 100644
index 0000000..7631297
--- /dev/null
+++ b/core/modules/search/templates/search-results.html.twig
@@ -0,0 +1,34 @@
+{#
+/**
+ * @file
+ * Default theme implementation for displaying search results.
+ *
+ * This template collects each invocation of theme_search_result(). This and
+ * the child template are dependent to one another sharing the markup for
+ * definition lists.
+ *
+ * Note that modules may implement their own search type and theme function
+ * completely bypassing this template.
+ *
+ * Available variables:
+ * - search_results: All results as it is rendered through search-result.tpl.php
+ * - module: The machine-readable name of the module (tab) being searched, such
+ *   as 'node' or 'user'
+ * - pager: The pager next/prev links to display, if any.
+ * - help: HTML for help text to display when no results are found.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_search_results()
+ *
+ * @ingroup themeable
+#}
+{% if search_results %}
+  <h2>{{ 'Search results'|t }}</h2>
+  <ol class="search-results {{ module }}-results">
+    {{ search_results }}
+  </ol>
+  {{ pager }}
+{% else %}
+  <h2>{{ 'Your search yielded no results'|t }}</h2>
+  {{ help }}
+{% endif %}
diff --git a/core/modules/search/templates/search-results.tpl.php b/core/modules/search/templates/search-results.tpl.php
deleted file mode 100644
index aa9bf8d..0000000
--- a/core/modules/search/templates/search-results.tpl.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for displaying search results.
- *
- * This template collects each invocation of theme_search_result(). This and
- * the child template are dependent to one another sharing the markup for
- * definition lists.
- *
- * Note that modules may implement their own search type and theme function
- * completely bypassing this template.
- *
- * Available variables:
- * - $search_results: All results as it is rendered through
- *   search-result.tpl.php
- * - $module: The machine-readable name of the module (tab) being searched, such
- *   as "node" or "user".
- *
- *
- * @see template_preprocess_search_results()
- *
- * @ingroup themeable
- */
-?>
-<?php if ($search_results): ?>
-  <h2><?php print t('Search results');?></h2>
-  <ol class="search-results <?php print $module; ?>-results">
-    <?php print $search_results; ?>
-  </ol>
-  <?php print $pager; ?>
-<?php else : ?>
-  <h2><?php print t('Your search yielded no results');?></h2>
-  <?php print search_help('search#noresults', drupal_help_arg()); ?>
-<?php endif; ?>
