diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index a56c1ef..6340395 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -402,7 +402,7 @@ function hook_entity_view(\Drupal\Core\Entity\EntityInterface $entity, \Drupal\e
  * If a module wishes to act on the rendered HTML of the entity rather than the
  * structured content array, it may use this hook to add a #post_render
  * callback. Alternatively, it could also implement hook_preprocess_HOOK() for
- * the particular entity type template, if there is one (e.g., node.tpl.php).
+ * the particular entity type template, if there is one (e.g., node.html.twig).
  * See drupal_render() and theme() for details.
  *
  * @param $build
diff --git a/core/modules/edit/edit.module b/core/modules/edit/edit.module
index a6ee046..bbdf6e0 100644
--- a/core/modules/edit/edit.module
+++ b/core/modules/edit/edit.module
@@ -151,7 +151,7 @@ function edit_preprocess_field(&$variables) {
 }
 
 /**
- * Implements hook_preprocess_HOOK() for node.tpl.php.
+ * Implements hook_preprocess_HOOK() for node.html.twig.
  *
  * @todo Move towards hook_preprocess_entity() once that's available.
  */
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 880e335..7972b85 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -844,7 +844,7 @@ function locale_system_file_system_settings_submit(&$form, $form_state) {
 }
 
 /**
- * Implements hook_preprocess_HOOK() for node.tpl.php.
+ * Implements hook_preprocess_HOOK() for node.html.twig.
  */
 function locale_preprocess_node(&$variables) {
   if ($variables['node']->langcode != LANGUAGE_NOT_SPECIFIED) {
diff --git a/core/modules/node/content_types.inc b/core/modules/node/content_types.inc
index e838460..c4933fd 100644
--- a/core/modules/node/content_types.inc
+++ b/core/modules/node/content_types.inc
@@ -75,27 +75,20 @@ function node_overview_types() {
 }
 
 /**
- * Returns HTML for a node type description for the content type admin page.
+ * Prepares variables for node type description templates.
  *
- * @param $variables
+ * Default template: node-admin-overview.html.twig.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - name: The human-readable name of the content type.
  *   - type: An object containing the 'type' (machine name) and 'description' of
  *     the content type.
- *
- * @return string
- *   An HTML-formatted string of the description for this node type.
- *
- * @ingroup themeable
  */
-function theme_node_admin_overview($variables) {
-  $name = $variables['name'];
-  $type = $variables['type'];
-
-  $output = check_plain($name);
-  $output .= ' <small>' . t('(Machine name: @type)', array('@type' => $type->type)) . '</small>';
-  $output .= '<div class="description">' . filter_xss_admin($type->description) . '</div>';
-  return $output;
+function template_preprocess_node_admin_overview(&$variables) {
+  $variables['name'] = check_plain($variables['name']);
+  $variables['description'] = filter_xss_admin($variables['type']->description);
+  $variables['machine_name'] = $variables['type']->type;
 }
 
 /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
index f382457..7e394f3 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
@@ -134,7 +134,7 @@ function testMultilingualDisplaySettings() {
     $this->drupalGet("node/$node->nid");
     $body = $this->xpath('//article[@id=:id]//div[@class=:class]/descendant::p', array(
       ':id' => 'node-' . $node->nid,
-      ':class' => 'content',
+      ':class' => 'content ',
     ));
     $this->assertEqual(current($body), $node->body['en'][0]['value'], 'Node body found.');
   }
diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php
index 5854170..1f71807 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -706,7 +706,7 @@ function hook_node_prepare(\Drupal\Core\Entity\EntityInterface $node) {
  *   theming.
  *
  * @see template_preprocess_search_result()
- * @see search-result.tpl.php
+ * @see search-result.html.twig
  *
  * @ingroup node_api_hooks
  */
@@ -898,8 +898,8 @@ function hook_node_view(\Drupal\Core\Entity\EntityInterface $node, \Drupal\entit
  * If the module wishes to act on the rendered HTML of the node rather than the
  * structured content array, it may use this hook to add a #post_render
  * callback.  Alternatively, it could also implement hook_preprocess_HOOK() for
- * node.tpl.php. See drupal_render() and theme() documentation respectively for
- * details.
+ * node.html.twig. See drupal_render() and theme() documentation respectively
+ * for details.
  *
  * @param $build
  *   A renderable array representing the node content.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 36dcfe0..268f204 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -157,20 +157,25 @@ function node_theme() {
     'node_add_list' => array(
       'variables' => array('content' => NULL),
       'file' => 'node.pages.inc',
+      'template' => 'node-add-list',
     ),
     'node_preview' => array(
       'variables' => array('node' => NULL),
       'file' => 'node.pages.inc',
+      'template' => 'node-preview',
     ),
     'node_admin_overview' => array(
       'variables' => array('name' => NULL, 'type' => NULL),
       'file' => 'content_types.inc',
+      'template' => 'node-admin-overview',
     ),
     'node_recent_block' => array(
       'variables' => array('nodes' => NULL),
+      'template' => 'node-recent-block',
     ),
     'node_recent_content' => array(
       'variables' => array('node' => NULL),
+      'template' => 'node-recent-content',
     ),
     'node_edit_form' => array(
       'render element' => 'form',
@@ -1129,19 +1134,39 @@ function node_preprocess_block(&$variables) {
 }
 
 /**
- * Processes variables for node.tpl.php.
+ * Prepares variables for node edit form templates.
  *
- * Most themes utilize their own copy of node.tpl.php. The default is located
- * inside "modules/node/node.tpl.php". Look in there for the full list of
- * variables.
+ * Default template: node-edit-form.html.twig.
  *
- * @param $variables
+ * @param array $variables
+ *   An associative array containing:
+ *   - form: The complete node form.
+ */
+function template_preprocess_node_edit_form(&$variables) {
+  $form = $variables['form'];
+
+  // @todo Remove this preprocess function once http://drupal.org/node/1920886
+  //   is resolved.
+  $variables['advanced'] = $form['advanced'];
+  $variables['actions'] = $form['actions'];
+  unset($form['advanced'], $form['actions']);
+  $variables['form'] = drupal_render_children($form);
+}
+
+/**
+ * Prepares variables for node templates.
+ *
+ * Default template: node.html.twig.
+ *
+ * Most themes utilize their own copy of node.html.twig. The default is located
+ * inside "core/modules/node/templates/node.html.twig". Look in there for the
+ * full list of variables.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - elements: An array of elements to display in view mode.
  *   - node: The node object.
  *   - view_mode: View mode; e.g., 'full', 'teaser'...
- *
- * @see node.tpl.php
  */
 function template_preprocess_node(&$variables) {
   $variables['view_mode'] = $variables['elements']['#view_mode'];
@@ -1150,25 +1175,18 @@ function template_preprocess_node(&$variables) {
   $variables['node'] = $variables['elements']['#node'];
   $node = $variables['node'];
 
-  $variables['date']      = format_date($node->created);
-  $variables['name']      = theme('username', array(
+  $variables['date'] = format_date($node->created);
+  // @todo Change 'name' to 'author' and also convert to a render array pending
+  //   http://drupal.org/node/1941286.
+  $variables['name'] = theme('username', array(
     'account' => $node,
     'link_attributes' => array('rel' => 'author'),
   ));
 
   $uri = $node->uri();
   $variables['node_url']  = url($uri['path'], $uri['options']);
-  $variables['label']     = check_plain($node->label());
-  $variables['page']      = $variables['view_mode'] == 'full' && node_is_page($node);
-
-  // Make useful flags and node data available.
-  // @todo: The comment properties only exist if comment.module is enabled, but
-  //   are documented in node.tpl.php, so we make sure that they are set.
-  //   Consider removing them.
-  $properties = array('type', 'comment_count', 'uid', 'created', 'promote', 'sticky', 'status', 'comment');
-  foreach ($properties as $property) {
-    $variables[$property] = isset($node->$property) ? $node->$property : NULL;
-  }
+  $variables['label'] = check_plain($node->label());
+  $variables['page'] = $variables['view_mode'] == 'full' && node_is_page($node);
 
   // Helpful $content variable for templates.
   $variables += array('content' => array());
@@ -1923,23 +1941,27 @@ function node_get_recent($number = 10) {
 }
 
 /**
- * Returns HTML for a list of recent content.
+ * Prepares variables for list of recent content templates.
  *
- * @param $variables
+ * Default template: node-recent-content.html.twig.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - nodes: An array of recent node entities.
  *
- * @ingroup themeable
+ * @see template_preprocess_node_recent_content()
  */
-function theme_node_recent_block($variables) {
+function template_preprocess_node_recent_block(&$variables) {
   $rows = array();
-  $output = '';
 
   $l_options = array('query' => drupal_get_destination());
   foreach ($variables['nodes'] as $node) {
     $row = array();
     $row[] = array(
-      'data' => theme('node_recent_content', array('node' => $node)),
+      'data' => array(
+        '#theme' => 'node_recent_content',
+        '#node' => $node,
+      ),
       'class' => 'title-author',
     );
     if (node_access('update', $node)) {
@@ -1957,36 +1979,44 @@ function theme_node_recent_block($variables) {
     $rows[] = $row;
   }
 
+  $variables['table'] = array(
+    '#theme' => 'table',
+  );
+  $variables['more_link'] = array();
   if ($rows) {
-    $output = theme('table', array('rows' => $rows));
+    $variables['table']['#rows'] = $rows;
     if (user_access('access content overview')) {
-      $output .= theme('more_link', array('url' => 'admin/content', 'title' => t('Show more content')));
+      $variables['more_link'] = array(
+        '#theme' => 'more_link',
+        '#url' => 'admin/content',
+        '#title' => t('Show more content'),
+      );
     }
   }
-
-  return $output;
 }
 
 /**
- * Returns HTML for a recent node to be displayed in the recent content block.
+ * Prepares variables for recently created node templates.
  *
- * @param $variables
+ * Default template: node-recent-content.twig.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - node: A node entity.
  *
- * @ingroup themeable
+ * @see template_preprocess_node_recent_block()
  */
-function theme_node_recent_content($variables) {
+function template_preprocess_node_recent_content(&$variables) {
   $node = $variables['node'];
-
-  $output = '<div class="node-title">';
-  $output .= l($node->label(), 'node/' . $node->nid);
-  $output .= theme('mark', array('type' => node_mark($node->nid, $node->changed)));
-  $output .= '</div><div class="node-author">';
-  $output .= theme('username', array('account' => user_load($node->uid)));
-  $output .= '</div>';
-
-  return $output;
+  $variables['link'] = l($node->label(), 'node/' . $node->nid);
+  $variables['mark'] = array(
+    '#theme' => 'mark',
+    '#type' => node_mark($node->nid, $node->changed),
+  );
+  $variables['username'] = array(
+    '#theme' => 'username',
+    '#account' => user_load($node->uid),
+  );
 }
 
 /**
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index 863babd..3df5b7c 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -56,32 +56,27 @@ function node_add_page() {
 }
 
 /**
- * Returns HTML for a list of available node types for node creation.
+ * Prepares variables for list of available node type templates.
  *
- * @param $variables
+ * Default template: node-add-list.html.twig.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - content: An array of content types.
  *
  * @see node_add_page()
- *
- * @ingroup themeable
  */
-function theme_node_add_list($variables) {
-  $content = $variables['content'];
-  $output = '';
-
-  if ($content) {
-    $output = '<dl class="node-type-list">';
-    foreach ($content as $type) {
-      $output .= '<dt>' . l($type->name, 'node/add/' . $type->type) . '</dt>';
-      $output .= '<dd>' . filter_xss_admin($type->description) . '</dd>';
+function template_preprocess_node_add_list(&$variables) {
+  $variables['types'] = array();
+  if (!empty($variables['content'])) {
+    foreach ($variables['content'] as $type) {
+      $variables['types'][$type->type] = array(
+        'type' => $type->type,
+        'add_link' => l($type->name, 'node/add/' . $type->type),
+        'description' => filter_xss_admin($type->description),
+      );
     }
-    $output .= '</dl>';
   }
-  else {
-    $output = '<p>' . t('You have not created any content types yet. Go to the <a href="@create-content">content type creation page</a> to add a new content type.', array('@create-content' => url('admin/structure/types/add'))) . '</p>';
-  }
-  return $output;
 }
 
 
@@ -157,41 +152,37 @@ function node_preview(EntityInterface $node) {
 }
 
 /**
- * Returns HTML for a node preview for display during node creation and editing.
+ * Prepares variables for node preview templates.
  *
- * @param $variables
+ * Default template: node-preview.html.twig.
+ *
+ * @param array $variables
  *   An associative array containing:
  *   - node: The node entity which is being previewed.
  *
  * @see NodeFormController::preview()
  * @see node_preview()
- *
- * @ingroup themeable
  */
-function theme_node_preview($variables) {
+function template_preprocess_node_preview(&$variables) {
   $node = $variables['node'];
 
-  $output = '';
-
-  $elements = node_view($node, 'teaser');
-  $elements['#attached']['library'][] = array('node', 'drupal.node.preview');
-  $trimmed = drupal_render($elements);
-  $elements = node_view($node, 'full');
-  $full = drupal_render($elements);
-
-  // Do we need to preview trimmed version of post as well as full version?
-  if ($trimmed != $full) {
+  // Render trimmed teaser version of the post.
+  $node_teaser = node_view($node, 'teaser');
+  $node_teaser['#attached']['library'][] = array('node', 'drupal.node.preview');
+  $variables['teaser'] = $node_teaser;
+  // Render full version of the post.
+  $node_full = node_view($node, 'full');
+  $variables['full'] = $node_full;
+
+  // Do we need to preview a trimmed teaser version of a post as well as a full
+  // version?
+  if ($variables['teaser'] != $variables['full']) {
     drupal_set_message(t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication.<span class="no-js"> You can insert the delimiter "&lt;!--break--&gt;" (without the quotes) to fine-tune where your post gets split.</span>'));
-    $output .= '<h3>' . t('Preview trimmed version') . '</h3>';
-    $output .= $trimmed;
-    $output .= '<h3>' . t('Preview full version') . '</h3>';
-    $output .= $full;
+    $variables['preview_teaser'] = TRUE;
   }
   else {
-    $output .= $full;
+    $variables['preview_teaser'] = FALSE;
   }
-
-  return $output;
 }
 
 /**
diff --git a/core/modules/node/templates/node-add-list.html.twig b/core/modules/node/templates/node-add-list.html.twig
new file mode 100644
index 0000000..5afc11d
--- /dev/null
+++ b/core/modules/node/templates/node-add-list.html.twig
@@ -0,0 +1,28 @@
+{#
+/**
+ * @file
+ * Default theme implementation to list node types available for adding content.
+ *
+ * This list is displayed on the add content admin page.
+ *
+ * Available variables:
+ * - types: A list of content types.
+ *   - type.add_link: Link to create a piece of content of this type.
+ *   - type.description: Description of this type of content.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_node_add_list()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if types is not empty %}
+  <dl class="node-type-list">
+    {% for type in types %}
+      <dt>{{ type.add_link }}</dt>
+      <dd>{{ type.description }}</dd>
+    {% endfor %}
+  </dl>
+{% else %}
+  <p>{{ 'You have not created any content types yet. Go to the <a href="@create-content">content type creation page</a> to add a new content type.'|t({'@create-content': url('admin/structure/types/add')}) }}</p>
+{% endif %}
diff --git a/core/modules/node/templates/node-admin-overview.html.twig b/core/modules/node/templates/node-admin-overview.html.twig
new file mode 100644
index 0000000..7438945
--- /dev/null
+++ b/core/modules/node/templates/node-admin-overview.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a node type description.
+ *
+ * This description is used for the content types admin page.
+ *
+ * Available variables:
+ * - name: Human readable name of the content type.
+ * - machine_name: Machine readable name of the content type.
+ * - description: Description of the content type.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_node_admin_overview()
+ *
+ * @ingroup themeable
+ */
+#}
+{{ name }} <small>{{ '(Machine name: @type)'|t({'@type': machine_name}) }}</small>
+<div class="description">{{ description }}</div>
diff --git a/core/modules/node/templates/node-edit-form.html.twig b/core/modules/node/templates/node-edit-form.html.twig
new file mode 100644
index 0000000..9840a5e
--- /dev/null
+++ b/core/modules/node/templates/node-edit-form.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Two column template for the node add/edit form.
+ *
+ * Available variables:
+ * - form: The remainder of the node edit form, after advanced and actions
+ *   have been hidden.
+ * - advanced: The advanced options for the node form.
+ * - actions: The action buttons for save and delete.
+ *
+ * @ingroup themable
+ */
+#}
+<div class="layout-node-form clearfix">
+  <div class="layout-region layout-region-node-main">
+    {{ form }}
+  </div>
+  <div class="layout-region layout-region-node-secondary">
+    {{ advanced }}
+  </div>
+  <div class="layout-region layout-region-node-footer">
+    {{ actions }}
+  </div>
+</div>
diff --git a/core/modules/node/templates/node-edit-form.tpl.php b/core/modules/node/templates/node-edit-form.tpl.php
deleted file mode 100644
index 7b76683..0000000
--- a/core/modules/node/templates/node-edit-form.tpl.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-/**
- * @file
- * Two column template for the node add/edit form.
- *
- * Available variables:
- * - $form: The actual form to print.
- */
-
-hide($form['advanced']);
-hide($form['actions']);
-
-?>
-<div class="layout-node-form clearfix">
-  <div class="layout-region layout-region-node-main">
-    <?php print drupal_render_children($form); ?>
-  </div>
-
-  <div class="layout-region layout-region-node-secondary">
-    <?php print render($form['advanced']); ?>
-  </div>
-
-  <div class="layout-region layout-region-node-footer">
-    <?php print render($form['actions']); ?>
-  </div>
-</div>
diff --git a/core/modules/node/templates/node-preview.html.twig b/core/modules/node/templates/node-preview.html.twig
new file mode 100644
index 0000000..aa8ec0e
--- /dev/null
+++ b/core/modules/node/templates/node-preview.html.twig
@@ -0,0 +1,24 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a node preview.
+ *
+ * This display may be used during node creation and editing.
+ *
+ * Available variables:
+ * - preview_teaser: Flag indicating whether to show a trimmed teaser version.
+ * - teaser: Trimmed teaser version of the node.
+ * - full: Full version of the node.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_node_preview()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if preview_teaser %}
+  <h3>{{ "Preview trimmed version"|t }}</h3>
+  {{ teaser }}
+  <h3>{{ "Preview full version"|t }}</h3>
+{% endif %}
+{{ full }}
diff --git a/core/modules/node/templates/node-recent-block.html.twig b/core/modules/node/templates/node-recent-block.html.twig
new file mode 100644
index 0000000..b8cfd81
--- /dev/null
+++ b/core/modules/node/templates/node-recent-block.html.twig
@@ -0,0 +1,21 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a list of recent content.
+ *
+ * Available variables:
+ * - table: A rendered HTML table of recent content.
+ * - more_link: A rendered link to show more content.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_node_recent_block()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if table %}
+  {{ table }}
+{% endif %}
+{% if more_link %}
+  {{ more_link }}
+{% endif %}
diff --git a/core/modules/node/templates/node-recent-content.html.twig b/core/modules/node/templates/node-recent-content.html.twig
new file mode 100644
index 0000000..f1a6d34
--- /dev/null
+++ b/core/modules/node/templates/node-recent-content.html.twig
@@ -0,0 +1,18 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a node in the recent content block.
+ *
+ * Available variables:
+ * - link: Link to the content.
+ * - mark: HTML marker for new or updated content.
+ * - username: The author of the content.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_node_recent_content()
+ *
+ * @ingroup themeable
+ */
+#}
+<div class="node-title">{{ link }}{{ mark }}</div>
+<div class="node-author">{{ username }}</div>
diff --git a/core/modules/node/templates/node.html.twig b/core/modules/node/templates/node.html.twig
index f1e0b5a..1c0fcf7 100644
--- a/core/modules/node/templates/node.html.twig
+++ b/core/modules/node/templates/node.html.twig
@@ -4,57 +4,55 @@
  * Default theme implementation to display a node.
  *
  * Available variables:
- * - label: the title of the node.
- * - content: node items. Use {{ content }} to print them all,
+ * - label: The node title.
+ * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {% hide(content.field_example) %} to temporarily suppress the printing
  *   of a given element.
+ * - name: Themed username of node author output from username.html.twig.
  * - user_picture: The node author's picture from user-picture.html.twig.
  * - date: Formatted creation date. Preprocess functions can reformat it by
  *   calling format_date() with the desired parameters on
  *   $variables['created'].
- * - name: Themed username of node author output from theme_username().
  * - node_url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - submitted: Submission information created from name and date during
  *   template_preprocess_node().
- * - attributes: HTML attributes for the surrounding element.
- *    Attributes include the 'class' information, which contains:
- *   - node: The current template type; for example, "theming hook".
- *   - node-[type]: The current node type. For example, if the node is a
- *     "Article" it would result in "node-article". Note that the machine
- *     name will often be in a short form of the human readable label.
- *   - view-mode-[view_mode]: The View Mode of the node; for example, "teaser"
- *     or "full".
- *   - preview: Nodes in preview mode.
- *   The following are controlled through the node publishing options.
- *   - promoted: Nodes promoted to the front page.
- *   - sticky: Nodes ordered above other non-sticky nodes in teaser
- *     listings.
- *   - unpublished: Unpublished nodes visible only to administrators.
+ * - attributes: Remaining HTML attributes for the containing element.
+ *   - attributes.class: Class information, containing:
+ *     - node: The current template type (also known as a "theming hook").
+ *     - node-[type]: The current node type. For example, if the node is a
+ *       "Article" it would result in "node-article". Note that the machine
+ *       name will often be in a short form of the human readable label.
+ *     - view-mode-[view_mode]: The View Mode of the node; for example, a teaser
+ *       would result in: "view-mode-teaser", and full: "view-mode-full".
+ *     - preview: Whether a node is in preview mode.
+ *     The following are controlled through the node publishing options.
+ *     - promoted: Appears on nodes promoted to the front page.
+ *     - sticky: Appears on nodes ordered above other non-sticky nodes in teaser
+ *       listings.
+ *     - unpublished: Appears on unpublished nodes visible only to site admins.
  * - 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.
  *
  * Other variables:
- * - node: Fully loaded node entity.
- * - type: Node type; for example, page, article, etc.
- * - comment_count: Number of comments attached to the node.
- * - uid: User ID of the node author.
- * - created: Time the node was published formatted as a Unix timestamp.
+ * - node: Full node entity.
+ *   - node.type: Node type; for example, "page" or "article".
+ *   - node.uid: User ID of the node author.
+ *   - node.created: Formatted creation date.
+ *   - node.promote: Flag for front page promotion state.
+ *   - node.sticky: Flag for sticky post setting.
+ *   - node.status: Flag for published status.
+ *   - node.comment: State of comment settings for the node.
+ *   - node.comment_count: Number of comments attached to the node.
  * - zebra: Outputs either "even" or "odd". Useful for zebra striping in
  *   teaser listings.
  * - id: Position of the node. Increments each time it's output.
- *
- * Node status variables:
  * - view_mode: View mode; for example, "teaser" or "full".
  * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
  * - page: Flag for the full page state. Will be true if view_mode is 'full'.
- * - promote: Flag for front page promotion state.
- * - sticky: Flag for sticky post setting.
- * - status: Flag for published status.
- * - comment: State of comment settings for the node.
  * - readmore: Flag for more state. Will be true if the teaser content of the
  *   node cannot hold the main body content.
  * - is_front: Flag for front. Will be true when presented on the front page.
@@ -64,25 +62,27 @@
  *   is an administrator.
  *
  * Field variables: for each field instance attached to the node a corresponding
- * variable is defined; for example, $node->body becomes body. When needing to
+ * variable is defined; for example, 'node.body' becomes 'body'. When needing to
  * access a field's raw values, developers/themers are strongly encouraged to
  * use these variables. Otherwise they will have to explicitly specify the
- * desired field language; for example, $node->body['en'], thus overriding any
- * language negotiation rule that was previously applied.
+ * desired field language; for example, 'node.body.en', thus overriding any
+ * language negotiation rule that may have been applied previously.
  *
  * @see template_preprocess()
  * @see template_preprocess_node()
  *
+ * @todo Remove the id attribute (or make it a class), because if that gets
+ *   rendered twice on a page this is invalid CSS for example: two lists
+ *   in different view modes.
+ *
  * @ingroup themeable
  */
 #}
-<article id="node-{{ node.nid }}" class="{{ attributes.class }} clearfix"{{ attributes }}>
+<article id="node-{{ node.nid }}" class="clearfix {{ attributes.class }}"{{ attributes }}>
 
   {{ title_prefix }}
   {% if not page %}
-    <h2{{ title_attributes }}>
-      <a href="{{ node_url }}" rel="bookmark">{{ label }}</a>
-    </h2>
+    <h2{{ title_attributes }}><a href="{{ node_url }}" rel="bookmark">{{ label }}</a></h2>
   {% endif %}
   {{ title_suffix }}
 
@@ -93,7 +93,7 @@
     </footer>
   {% endif %}
 
-  <div class="content"{{ content_attributes }}>
+  <div class="content {{ content_attributes.class }}"{{ content_attributes }}>
     {# We hide the comments and links now so that we can render them later. #}
     {% hide(content.comments) %}
     {% hide(content.links) %}
diff --git a/core/modules/node/templates/node.tpl.php b/core/modules/node/templates/node.tpl.php
deleted file mode 100644
index 196d26f..0000000
--- a/core/modules/node/templates/node.tpl.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display a node.
- *
- * Available variables:
- * - $label: the (sanitized) title of the node.
- * - $content: An array of node items. Use render($content) to print them all,
- *   or print a subset such as render($content['field_example']). Use
- *   hide($content['field_example']) to temporarily suppress the printing of a
- *   given element.
- * - $user_picture: The node author's picture. Use render() to print it.
- * - $date: Formatted creation date. Preprocess functions can reformat it by
- *   calling format_date() with the desired parameters on the $created variable.
- * - $name: Themed username of node author output from theme_username().
- * - $node_url: Direct URL of the current node.
- * - $display_submitted: Whether submission information should be displayed.
- * - $submitted: Submission information created from $name and $date during
- *   template_preprocess_node().
- * - $attributes: An instance of Attributes class that can be manipulated as an
- *    array and printed as a string.
- *    It includes the 'class' information, which includes:
- *   - node: The current template type; for example, "theming hook".
- *   - node-[type]: The current node type. For example, if the node is a
- *     "Article" it would result in "node-article". Note that the machine
- *     name will often be in a short form of the human readable label.
- *   - view-mode-[view_mode]: The View Mode of the node; for example, "teaser"
- *     or "full".
- *   - preview: Nodes in preview mode.
- *   The following are controlled through the node publishing options.
- *   - promoted: Nodes promoted to the front page.
- *   - sticky: Nodes ordered above other non-sticky nodes in teaser
- *     listings.
- *   - unpublished: Unpublished nodes visible only to administrators.
- * - $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.
- *
- * Other variables:
- * - $node: Full node entity. Contains data that may not be safe.
- * - $type: Node type; for example, page, article, etc.
- * - $comment_count: Number of comments attached to the node.
- * - $uid: User ID of the node author.
- * - $created: Time the node was published formatted in Unix timestamp.
- * - $zebra: Outputs either "even" or "odd". Useful for zebra striping in
- *   teaser listings.
- * - $id: Position of the node. Increments each time it's output.
- *
- * Node status variables:
- * - $view_mode: View mode; for example, "teaser" or "full".
- * - $teaser: Flag for the teaser state (shortcut for $view_mode == 'teaser').
- * - $page: Flag for the full page state.
- * - $promote: Flag for front page promotion state.
- * - $sticky: Flags for sticky post setting.
- * - $status: Flag for published status.
- * - $comment: State of comment settings for the node.
- * - $is_front: Flags true when presented in the front page.
- * - $logged_in: Flags true when the current user is a logged-in member.
- * - $is_admin: Flags true when the current user is an administrator.
- *
- * Field variables: for each field instance attached to the node a corresponding
- * variable is defined; for example, $node->body becomes $body. When needing to
- * access a field's raw values, developers/themers are strongly encouraged to
- * use these variables. Otherwise they will have to explicitly specify the
- * desired field language; for example, $node->body['en'], thus overriding any
- * language negotiation rule that was previously applied.
- *
- * @see template_preprocess()
- * @see template_preprocess_node()
- * @see template_process()
- *
- * @ingroup themeable
- */
-?>
-<article id="node-<?php print $node->nid; ?>" class="<?php print $attributes['class']; ?> clearfix"<?php print $attributes; ?>>
-
-  <?php print render($title_prefix); ?>
-  <?php if (!$page): ?>
-    <h2<?php print $title_attributes; ?>><a href="<?php print $node_url; ?>" rel="bookmark"><?php print $label; ?></a></h2>
-  <?php endif; ?>
-  <?php print render($title_suffix); ?>
-
-  <?php if ($display_submitted): ?>
-    <footer>
-      <?php print render($user_picture); ?>
-      <p class="submitted"><?php print $submitted; ?></p>
-    </footer>
-  <?php endif; ?>
-
-  <div class="content"<?php print $content_attributes; ?>>
-    <?php
-      // We hide the comments and links now so that we can render them later.
-      hide($content['comments']);
-      hide($content['links']);
-      print render($content);
-    ?>
-  </div>
-
-  <?php print render($content['links']); ?>
-  <?php print render($content['comments']); ?>
-
-</article>
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 547075a..a8be103 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -492,7 +492,7 @@ function rdf_preprocess_html(&$variables) {
 }
 
 /**
- * Implements hook_preprocess_HOOK() for node.tpl.php.
+ * Implements hook_preprocess_HOOK() for node.html.twig.
  */
 function rdf_preprocess_node(&$variables) {
   // Adds RDFa markup to the node container. The about attribute specifies the
@@ -509,7 +509,7 @@ function rdf_preprocess_node(&$variables) {
   $variables['title_attributes']['property'] = empty($variables['node']->rdf_mapping['title']['predicates']) ? NULL : $variables['node']->rdf_mapping['title']['predicates'];
   $variables['title_attributes']['datatype'] = '';
 
-  // In full node mode, the title is not displayed by node.tpl.php so it is
+  // In full node mode, the title is not displayed by node.html.twig so it is
   // added in the <head> tag of the HTML page.
   if ($variables['page']) {
     $element = array(
@@ -557,7 +557,7 @@ function rdf_preprocess_node(&$variables) {
       $variables['content']['links']['comment']['#links']['comment-comments']['attributes'] += $comment_count_attributes;
     }
     // In full node view, the number of comments is not displayed by
-    // node.tpl.php so it is expressed in RDFa in the <head> tag of the HTML
+    // node.html.twig so it is expressed in RDFa in the <head> tag of the HTML
     // page.
     if ($variables['page'] && user_access('access comments')) {
       $element = array(
@@ -843,8 +843,8 @@ function rdf_preprocess_image(&$variables) {
  *   - context: An array of context information about the content to be wrapped:
  *     - hook: The theme hook that will use the wrapped content. This
  *       corresponds to the key within the theme registry for this template.
- *       For example, if this content is about to be used in node.tpl.php or
- *       node-[type].tpl.php, then the 'hook' is 'node'.
+ *       For example, if this content is about to be used in node.html.twig or
+ *       node-[type].html.twig, then the 'hook' is 'node'.
  *     - variable_name: The name of the variable by which the template will
  *       refer to this content. Each template file has documentation about
  *       the variables it uses. For example, if this function is called in
