diff --git a/core/includes/ajax.inc b/core/includes/ajax.inc
index 31c099e04fd9cddc899b479deb1f5128479d70d5..7c4ac37c31251f56a1251321ee0a9b18fea18fa5 100644
--- a/core/includes/ajax.inc
+++ b/core/includes/ajax.inc
@@ -732,73 +732,6 @@ function ajax_command_insert($selector, $html, $settings = NULL) {
   );
 }
 
-/**
- * Creates a Drupal Ajax 'insert/replaceWith' command.
- *
- * The 'insert/replaceWith' command instructs the client to use jQuery's
- * replaceWith() method to replace each element matched matched by the given
- * selector with the given HTML.
- *
- * This command is implemented by Drupal.ajax.prototype.commands.insert()
- * defined in misc/ajax.js.
- *
- * @param $selector
- *   A jQuery selector string. If the command is a response to a request from
- *   an #ajax form element then this value can be NULL.
- * @param $html
- *   The data to use with the jQuery replaceWith() method.
- * @param $settings
- *   An optional array of settings that will be used for this command only.
- *
- * @return
- *   An array suitable for use with the ajax_render() function.
- *
- * See
- * @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink
- */
-function ajax_command_replace($selector, $html, $settings = NULL) {
-  return array(
-    'command' => 'insert',
-    'method' => 'replaceWith',
-    'selector' => $selector,
-    'data' => $html,
-    'settings' => $settings,
-  );
-}
-
-/**
- * Creates a Drupal Ajax 'insert/html' command.
- *
- * The 'insert/html' command instructs the client to use jQuery's html()
- * method to set the HTML content of each element matched by the given
- * selector while leaving the outer tags intact.
- *
- * This command is implemented by Drupal.ajax.prototype.commands.insert()
- * defined in misc/ajax.js.
- *
- * @param $selector
- *   A jQuery selector string. If the command is a response to a request from
- *   an #ajax form element then this value can be NULL.
- * @param $html
- *   The data to use with the jQuery html() method.
- * @param $settings
- *   An optional array of settings that will be used for this command only.
- *
- * @return
- *   An array suitable for use with the ajax_render() function.
- *
- * @see http://docs.jquery.com/Attributes/html#val
- */
-function ajax_command_html($selector, $html, $settings = NULL) {
-  return array(
-    'command' => 'insert',
-    'method' => 'html',
-    'selector' => $selector,
-    'data' => $html,
-    'settings' => $settings,
-  );
-}
-
 /**
  * Creates a Drupal Ajax 'insert/prepend' command.
  *
@@ -865,72 +798,6 @@ function ajax_command_append($selector, $html, $settings = NULL) {
   );
 }
 
-/**
- * Creates a Drupal Ajax 'insert/after' command.
- *
- * The 'insert/after' command instructs the client to use jQuery's after()
- * method to insert the given HTML content after each element matched by
- * the given selector.
- *
- * This command is implemented by Drupal.ajax.prototype.commands.insert()
- * defined in misc/ajax.js.
- *
- * @param $selector
- *   A jQuery selector string. If the command is a response to a request from
- *   an #ajax form element then this value can be NULL.
- * @param $html
- *   The data to use with the jQuery after() method.
- * @param $settings
- *   An optional array of settings that will be used for this command only.
- *
- * @return
- *   An array suitable for use with the ajax_render() function.
- *
- * @see http://docs.jquery.com/Manipulation/after#content
- */
-function ajax_command_after($selector, $html, $settings = NULL) {
-  return array(
-    'command' => 'insert',
-    'method' => 'after',
-    'selector' => $selector,
-    'data' => $html,
-    'settings' => $settings,
-  );
-}
-
-/**
- * Creates a Drupal Ajax 'insert/before' command.
- *
- * The 'insert/before' command instructs the client to use jQuery's before()
- * method to insert the given HTML content before each of elements matched by
- * the given selector.
- *
- * This command is implemented by Drupal.ajax.prototype.commands.insert()
- * defined in misc/ajax.js.
- *
- * @param $selector
- *   A jQuery selector string. If the command is a response to a request from
- *   an #ajax form element then this value can be NULL.
- * @param $html
- *   The data to use with the jQuery before() method.
- * @param $settings
- *   An optional array of settings that will be used for this command only.
- *
- * @return
- *   An array suitable for use with the ajax_render() function.
- *
- * @see http://docs.jquery.com/Manipulation/before#content
- */
-function ajax_command_before($selector, $html, $settings = NULL) {
-  return array(
-    'command' => 'insert',
-    'method' => 'before',
-    'selector' => $selector,
-    'data' => $html,
-    'settings' => $settings,
-  );
-}
-
 /**
  * Creates a Drupal Ajax 'remove' command.
  *
@@ -1043,91 +910,6 @@ function ajax_command_settings($argument, $merge = FALSE) {
   );
 }
 
-/**
- * Creates a Drupal Ajax 'data' command.
- *
- * The 'data' command instructs the client to attach the name=value pair of
- * data to the selector via jQuery's data cache.
- *
- * This command is implemented by Drupal.ajax.prototype.commands.data()
- * defined in misc/ajax.js.
- *
- * @param $selector
- *   A jQuery selector string. If the command is a response to a request from
- *   an #ajax form element then this value can be NULL.
- * @param $name
- *   The name or key (in the key value pair) of the data attached to this
- *   selector.
- * @param $value
- *   The value of the data. Not just limited to strings can be any format.
- *
- * @return
- *   An array suitable for use with the ajax_render() function.
- *
- * @see http://docs.jquery.com/Core/data#namevalue
- */
-function ajax_command_data($selector, $name, $value) {
-  return array(
-    'command' => 'data',
-    'selector' => $selector,
-    'name' => $name,
-    'value' => $value,
-  );
-}
-
-/**
- * Creates a Drupal Ajax 'invoke' command.
- *
- * The 'invoke' command will instruct the client to invoke the given jQuery
- * method with the supplied arguments on the elements matched by the given
- * selector. Intended for simple jQuery commands, such as attr(), addClass(),
- * removeClass(), toggleClass(), etc.
- *
- * This command is implemented by Drupal.ajax.prototype.commands.invoke()
- * defined in misc/ajax.js.
- *
- * @param $selector
- *   A jQuery selector string. If the command is a response to a request from
- *   an #ajax form element then this value can be NULL.
- * @param $method
- *   The jQuery method to invoke.
- * @param $args
- *   (optional) A list of arguments to the jQuery $method, if any.
- *
- * @return
- *   An array suitable for use with the ajax_render() function.
- */
-function ajax_command_invoke($selector, $method, array $args = array()) {
-  return array(
-    'command' => 'invoke',
-    'selector' => $selector,
-    'method' => $method,
-    'args' => $args,
-  );
-}
-
-/**
- * Creates a Drupal Ajax 'restripe' command.
- *
- * The 'restripe' command instructs the client to restripe a table. This is
- * usually used after a table has been modified by a replace or append command.
- *
- * This command is implemented by Drupal.ajax.prototype.commands.restripe()
- * defined in misc/ajax.js.
- *
- * @param $selector
- *   A jQuery selector string.
- *
- * @return
- *   An array suitable for use with the ajax_render() function.
- */
-function ajax_command_restripe($selector) {
-  return array(
-    'command' => 'restripe',
-    'selector' => $selector,
-  );
-}
-
 /**
  * Creates a Drupal Ajax 'add_css' command.
  *
diff --git a/core/modules/system/lib/Drupal/system/Tests/Ajax/FrameworkTest.php b/core/modules/system/lib/Drupal/system/Tests/Ajax/FrameworkTest.php
index 2350e2f465368af6a8d9d6a2a4fb86be66754a27..699538e05eaed49b6698a01f8d0de92045bccd69 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Ajax/FrameworkTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Ajax/FrameworkTest.php
@@ -83,11 +83,6 @@ function testOrder() {
    * Tests behavior of ajax_render_error().
    */
   function testAJAXRenderError() {
-    // Verify default error message.
-    $commands = $this->drupalGetAJAX('ajax-test/render-error');
-    $expected = new AlertCommand(t('An error occurred while handling the request: The server received invalid input.'));
-    $this->assertCommand($commands, $expected->render(), 'ajax_render_error() invokes alert command.');
-
     // Verify custom error message.
     $edit = array(
       'message' => 'Custom error message.',
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 52037472340b872bdec47882e80c16d6aa1042da..2d45a6216288071e75bc063b3bccbc887bf3f6dd 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -5,6 +5,8 @@
  * Admin page callbacks for the system module.
  */
 
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\ReplaceCommand;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -2919,8 +2921,9 @@ function system_date_time_lookup($form, &$form_state) {
   // Return a command instead of a string, since the Ajax framework
   // automatically prepends an additional empty DIV element for a string, which
   // breaks the layout.
-  $commands[] = ajax_command_replace('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>'));
+  return $response;
 }
 
 /**
diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
index 3e66bdca2ce04db66cab420b0508da1ff8d61b78..e0e9c155655c18a374032e8b0001541fdcc03b91 100644
--- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
+++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
@@ -5,6 +5,8 @@
  * Simpletest mock module for Ajax forms testing.
  */
 
+use Drupal\Core\Ajax;
+use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\ajax_forms_test\Callbacks;
 
 /**
@@ -271,18 +273,18 @@ function ajax_forms_test_ajax_commands_form($form, &$form_state) {
 function ajax_forms_test_advanced_commands_after_callback($form, $form_state) {
   $selector = '#after_div';
 
-  $commands = array();
-  $commands[] = ajax_command_after($selector, "This will be placed after");
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\AfterCommand($selector, "This will be placed after"));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'alert'.
  */
 function ajax_forms_test_advanced_commands_alert_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_alert("Alert");
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\AlertCommand('Alert'));
+  return $response;
 }
 
 /**
@@ -290,9 +292,9 @@ function ajax_forms_test_advanced_commands_alert_callback($form, $form_state) {
  */
 function ajax_forms_test_advanced_commands_append_callback($form, $form_state) {
   $selector = '#append_div';
-  $commands = array();
-  $commands[] = ajax_command_append($selector, "Appended text");
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\AppendCommand($selector, "Appended text"));
+  return $response;
 }
 
 /**
@@ -300,27 +302,27 @@ function ajax_forms_test_advanced_commands_append_callback($form, $form_state) {
  */
 function ajax_forms_test_advanced_commands_before_callback($form, $form_state) {
   $selector = '#before_div';
-
-  $commands = array();
-  $commands[] = ajax_command_before($selector, "Before text");
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\BeforeCommand($selector, "Before text"));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'changed'.
  */
 function ajax_forms_test_advanced_commands_changed_callback($form, $form_state) {
-  $commands[] = ajax_command_changed('#changed_div');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\ChangedCommand('#changed_div'));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'changed' with asterisk marking inner div.
  */
 function ajax_forms_test_advanced_commands_changed_asterisk_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_changed('#changed_div', '#changed_div_mark_this');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\ChangedCommand('#changed_div', '#changed_div_mark_this'));
+  return $response;
 }
 
 /**
@@ -330,9 +332,9 @@ function ajax_forms_test_advanced_commands_css_callback($form, $form_state) {
   $selector = '#css_div';
   $color = 'blue';
 
-  $commands = array();
-  $commands[] = ajax_command_css($selector, array('background-color' => $color));
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\CssCommand($selector, array('background-color' => $color)));
+  return $response;
 }
 
 /**
@@ -340,83 +342,82 @@ function ajax_forms_test_advanced_commands_css_callback($form, $form_state) {
  */
 function ajax_forms_test_advanced_commands_data_callback($form, $form_state) {
   $selector = '#data_div';
-
-  $commands = array();
-  $commands[] = ajax_command_data($selector, 'testkey', 'testvalue');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\DataCommand($selector, 'testkey', 'testvalue'));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'invoke'.
  */
 function ajax_forms_test_advanced_commands_invoke_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_invoke('#invoke_div', 'addClass', array('error'));
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\InvokeCommand('#invoke_div', 'addClass', array('error')));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'html'.
  */
 function ajax_forms_test_advanced_commands_html_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_html('#html_div', 'replacement text');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\HtmlCommand('#html_div', 'replacement text'));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'insert'.
  */
 function ajax_forms_test_advanced_commands_insert_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_insert('#insert_div', 'insert replacement text');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\InsertCommand('#insert_div', 'insert replacement text'));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'prepend'.
  */
 function ajax_forms_test_advanced_commands_prepend_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_prepend('#prepend_div', "prepended text");
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\PrependCommand('#prepend_div', "prepended text"));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'remove'.
  */
 function ajax_forms_test_advanced_commands_remove_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_remove('#remove_text');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\RemoveCommand('#remove_text'));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'restripe'.
  */
 function ajax_forms_test_advanced_commands_restripe_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_restripe('#restripe_table');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\RestripeCommand('#restripe_table'));
+  return $response;
 }
 
 /**
  * Ajax form callback: Selects 'settings'.
  */
 function ajax_forms_test_advanced_commands_settings_callback($form, $form_state) {
-  $commands = array();
   $setting['ajax_forms_test']['foo'] = 42;
-  $commands[] = ajax_command_settings($setting);
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\SettingsCommand($setting));
+  return $response;
 }
 
 /**
  * Ajax callback for 'add_css'.
  */
 function ajax_forms_test_advanced_commands_add_css_callback($form, $form_state) {
-  $commands = array();
-  $commands[] = ajax_command_add_css('my/file.css');
-  return array('#type' => 'ajax', '#commands' => $commands);
+  $response = new AjaxResponse();
+  $response->addCommand(new Ajax\AddCssCommand('my/file.css'));
+  return $response;
 }
 
 /**
@@ -426,7 +427,8 @@ function ajax_forms_test_advanced_commands_settings_with_merging_callback($form,
   drupal_add_js(array('ajax_forms_test' => array('foo' => 42)), 'setting');
   drupal_add_js(array('ajax_forms_test' => array('foo' => 9001)), 'setting');
 
-  return array('#type' => 'ajax', '#commands' => array());
+  $response = new AjaxResponse();
+  return $response;
 }
 
 /**
diff --git a/core/modules/system/tests/modules/ajax_forms_test/lib/Drupal/ajax_forms_test/Callbacks.php b/core/modules/system/tests/modules/ajax_forms_test/lib/Drupal/ajax_forms_test/Callbacks.php
index 92b50b854c2c2744be5a681891d5d44fa1f286fa..03f990248c19b81598b7042ca6ecbd6daf07393e 100644
--- a/core/modules/system/tests/modules/ajax_forms_test/lib/Drupal/ajax_forms_test/Callbacks.php
+++ b/core/modules/system/tests/modules/ajax_forms_test/lib/Drupal/ajax_forms_test/Callbacks.php
@@ -7,6 +7,10 @@
 
 namespace Drupal\ajax_forms_test;
 
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\DataCommand;
+use Drupal\Core\Ajax\HtmlCommand;
+
 /**
  * Simple object for testing methods as Ajax callbacks.
  */
@@ -16,19 +20,19 @@ class Callbacks {
    * Ajax callback triggered by select.
    */
   function selectCallback($form, $form_state) {
-    $commands = array();
-    $commands[] = ajax_command_html('#ajax_selected_color', $form_state['values']['select']);
-    $commands[] = ajax_command_data('#ajax_selected_color', 'form_state_value_select', $form_state['values']['select']);
-    return array('#type' => 'ajax', '#commands' => $commands);
+    $response = new AjaxResponse();
+    $response->addCommand(new HtmlCommand('#ajax_selected_color', $form_state['values']['select']));
+    $response->addCommand(new DataCommand('#ajax_selected_color', 'form_state_value_select', $form_state['values']['select']));
+    return $response;
   }
 
   /**
    * Ajax callback triggered by checkbox.
    */
   function checkboxCallback($form, $form_state) {
-    $commands = array();
-    $commands[] = ajax_command_html('#ajax_checkbox_value', (int) $form_state['values']['checkbox']);
-    $commands[] = ajax_command_data('#ajax_checkbox_value', 'form_state_value_select', (int) $form_state['values']['checkbox']);
-    return array('#type' => 'ajax', '#commands' => $commands);
+    $response = new AjaxResponse();
+    $response->addCommand(new HtmlCommand('#ajax_checkbox_value', (int) $form_state['values']['checkbox']));
+    $response->addCommand(new DataCommand('#ajax_checkbox_value', 'form_state_value_select', (int) $form_state['values']['checkbox']));
+    return $response;
   }
 }
diff --git a/core/modules/system/tests/modules/ajax_test/ajax_test.module b/core/modules/system/tests/modules/ajax_test/ajax_test.module
index 1cb6bf24955afadc273cfe5f1bd25c4c6177094e..2ed5a16631b34b8b5b79481bffab7a3ff6ab516f 100644
--- a/core/modules/system/tests/modules/ajax_test/ajax_test.module
+++ b/core/modules/system/tests/modules/ajax_test/ajax_test.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\AlertCommand;
 use Drupal\Core\Ajax\OpenDialogCommand;
 use Drupal\Core\Ajax\OpenModalDialogCommand;
 use Drupal\Core\Ajax\CloseDialogCommand;
@@ -70,7 +71,8 @@ function ajax_test_system_theme_info() {
  */
 function ajax_test_render() {
   drupal_add_js(array('ajax' => 'test'), 'setting');
-  return array('#type' => 'ajax', '#commands' => array());
+  $response = new AjaxResponse();
+  return $response;
 }
 
 /**
@@ -102,7 +104,9 @@ function ajax_test_error() {
   if (!empty($_GET['message'])) {
     $message = $_GET['message'];
   }
-  return array('#type' => 'ajax', '#error' => $message);
+  $response = new AjaxResponse();
+  $response->addCommand(new AlertCommand($message));
+  return $response;
 }
 
 /**