diff --git a/core/includes/common.inc b/core/includes/common.inc
index 44fa3674df94c29517eaf7bca506790967ebbffe..9a99bc32d4fafa1e50fd7bf1fae32ba2a054582d 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2727,18 +2727,6 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) {
   // Sort CSS items, so that they appear in the correct order.
   uasort($css, 'drupal_sort_css_js');
 
-  // Provide the page with information about the individual CSS files used,
-  // information not otherwise available when CSS aggregation is enabled. The
-  // setting is attached later in this function, but is set here, so that CSS
-  // files removed below are still considered "used" and prevented from being
-  // added in a later AJAX request.
-  // Skip if no files were added to the page or jQuery.extend() will overwrite
-  // the Drupal.settings.ajaxPageState.css object with an empty array.
-  if (!empty($css)) {
-    // Cast the array to an object to be on the safe side even if not empty.
-    $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1);
-  }
-
   // Remove the overridden CSS files. Later CSS files override former ones.
   $previous_item = array();
   foreach ($css as $key => $item) {
@@ -3806,55 +3794,33 @@ function drupal_add_js($data = NULL, $options = NULL) {
   // Tweak the weight so that files of the same weight are included in the
   // order of the calls to drupal_add_js().
   $options['weight'] += count($javascript) / 1000;
-
   if (isset($data)) {
-    // Add jquery.js and drupal.js, as well as the basePath setting, the
-    // first time a JavaScript file is added.
-    if (empty($javascript)) {
-      // url() generates the script and prefix using hook_url_outbound_alter().
-      // Instead of running the hook_url_outbound_alter() again here, extract
-      // them from url().
-      // @todo Make this less hacky: http://drupal.org/node/1547376.
-      $scriptPath = $GLOBALS['script_path'];
-      $pathPrefix = '';
-      url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix));
-      $javascript = array(
-        'settings' => array(
-          'data' => array(
-            array('basePath' => base_path()),
-            array('scriptPath' => $scriptPath),
-            array('pathPrefix' => $pathPrefix),
-            array('currentPath' => current_path()),
-          ),
-          'type' => 'setting',
-          'scope' => 'header',
-          'group' => JS_SETTING,
-          'every_page' => TRUE,
-          'weight' => 0,
-          'browsers' => array(),
-        ),
-        'core/misc/drupal.js' => array(
-          'data' => 'core/misc/drupal.js',
-          'type' => 'file',
-          'scope' => 'header',
-          'group' => JS_LIBRARY,
-          'every_page' => TRUE,
-          'weight' => -1,
-          'preprocess' => TRUE,
-          'cache' => TRUE,
-          'defer' => FALSE,
-          'async' => FALSE,
-          'browsers' => array(),
-        ),
-      );
-      // Register all required libraries.
-      drupal_add_library('system', 'jquery', TRUE);
-      drupal_add_library('system', 'jquery.once', TRUE);
-      drupal_add_library('system', 'html5shiv', TRUE);
-    }
-
     switch ($options['type']) {
       case 'setting':
+        // If the setting array doesn't exist, add defaults values.
+        if (!isset($javascript['settings'])) {
+          $javascript['settings'] = array(
+            'type' => 'setting',
+            'scope' => 'header',
+            'group' => JS_SETTING,
+            'every_page' => TRUE,
+            'weight' => 0,
+            'browsers' => array(),
+          );
+          // url() generates the script and prefix using hook_url_outbound_alter().
+          // Instead of running the hook_url_outbound_alter() again here, extract
+          // them from url().
+          // @todo Make this less hacky: http://drupal.org/node/1547376.
+          $scriptPath = $GLOBALS['script_path'];
+          $pathPrefix = '';
+          url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix));
+          $javascript['settings']['data'][] = array(
+            'basePath' => base_path(),
+            'scriptPath' => $scriptPath,
+            'pathPrefix' => $pathPrefix,
+            'currentPath' => current_path(),
+          );
+        }
         // All JavaScript settings are placed in the header of the page with
         // the library weight so that inline scripts appear afterwards.
         $javascript['settings']['data'][] = $data;
@@ -3953,23 +3919,59 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
     }
   }
 
-  // Sort the JavaScript so that it appears in the correct order.
-  uasort($items, 'drupal_sort_css_js');
+  if (!empty($items)) {
+    // Sort the JavaScript files so that they appear in the correct order.
+    uasort($items, 'drupal_sort_css_js');
+    // Don't add settings if there is no other JavaScript on the page, unless
+    // this is an AJAX request.
+    // @todo Clean up container call.
+    $container = drupal_container();
+    if ($container->has('request') && $container->has('content_negotiation')) {
+      $type = $container->get('content_negotiation')->getContentType($container->get('request'));
+    }
+    if (!empty($items['settings']) || (!empty($type) && $type == 'ajax')) {
+      global $theme_key;
+      // Provide the page with information about the theme that's used, so that
+      // a later AJAX request can be rendered using the same theme.
+      // @see ajax_base_page_theme()
+      $setting['ajaxPageState']['theme'] = $theme_key;
+      // Checks that the DB is available before filling theme_token.
+      if (!defined('MAINTENANCE_MODE')) {
+        $setting['ajaxPageState']['theme_token'] = drupal_get_token($theme_key);
+      }
+
+      // Provide the page with information about the individual JavaScript files
+      // used, information not otherwise available when aggregation is enabled.
+      $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
+      unset($setting['ajaxPageState']['js']['settings']);
+
+      // Provide the page with information about the individual CSS files used,
+      // information not otherwise available when CSS aggregation is enabled.
+      // The setting is attached later in this function, but is set here, so
+      // that CSS files removed in drupal_process_attached() are still
+      // considered "used" and prevented from being added in a later AJAX
+      // request.
+      // Skip if no files were added to the page otherwise jQuery.extend() will
+      // overwrite the Drupal.settings.ajaxPageState.css object with an empty
+      // array.
+      $css = drupal_add_css();
+      if (!empty($css)) {
+        // Cast the array to an object to be on the safe side even if not empty.
+        $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1);
+      }
 
-  // Provide the page with information about the individual JavaScript files
-  // used, information not otherwise available when aggregation is enabled.
-  $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
-  unset($setting['ajaxPageState']['js']['settings']);
-  drupal_add_js($setting, 'setting');
+      drupal_add_js($setting, 'setting');
 
-  // If we're outputting the header scope, then this might be the final time
-  // that drupal_get_js() is running, so add the setting to this output as well
-  // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
-  // because drupal_get_js() was intentionally passed a $javascript argument
-  // stripped of settings, potentially in order to override how settings get
-  // output, so in this case, do not add the setting to this output.
-  if ($scope == 'header' && isset($items['settings'])) {
-    $items['settings']['data'][] = $setting;
+      // If we're outputting the header scope, then this might be the final time
+      // that drupal_get_js() is running, so add the settings to this output as well
+      // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
+      // because drupal_get_js() was intentionally passed a $javascript argument
+      // stripped of settings, potentially in order to override how settings get
+      // output, so in this case, do not add the setting to this output.
+      if ($scope == 'header' && isset($items['settings'])) {
+        $items['settings']['data'][] = $setting;
+      }
+    }
   }
 
   // Render the HTML needed to load the JavaScript.
@@ -4235,7 +4237,7 @@ function drupal_aggregate_js(&$js_groups) {
  * are the attached data. For example:
  * @code
  * $build['#attached'] = array(
- *   'js' => array(drupal_get_path('module', 'taxonomy') . '/taxonomy.js'),
+ *   'library' => array(array('taxonomy', 'taxonomy')),
  *   'css' => array(drupal_get_path('module', 'taxonomy') . '/taxonomy.css'),
  * );
  * @endcode
diff --git a/core/includes/form.inc b/core/includes/form.inc
index ddd29e099f27e14ce41e210b825d2adffac3821e..ac789e185154dff4894a3bdba354f5bc98cb2127 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3424,7 +3424,7 @@ function theme_tableselect($variables) {
     // checkboxes/radios in the first table column.
     if ($element['#js_select']) {
       // Add a "Select all" checkbox.
-      drupal_add_js('core/misc/tableselect.js');
+      drupal_add_library('system', 'drupal.tableselect');
       array_unshift($header, array('class' => array('select-all')));
     }
     else {
@@ -3614,7 +3614,7 @@ function form_process_machine_name($element, &$form_state) {
       ),
     ),
   );
-  $element['#attached']['js'][] = 'core/misc/machine-name.js';
+  $element['#attached']['library'][] = array('system', 'drupal.machine-name');
   $element['#attached']['js'][] = $js_settings;
 
   return $element;
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 14b674d24ca6860ff5ff39dfdca35f5ed4081bed..cd90a79824a669b6330adc238f11b614af063a1f 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1531,9 +1531,9 @@ function install_configure_form($form, &$form_state, &$install_state) {
     drupal_set_message(st('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the <a href="@handbook_url">online handbook</a>.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning');
   }
 
-  drupal_add_js(drupal_get_path('module', 'system') . '/system.js');
+  drupal_add_library('system', 'drupal.system');
   // Add JavaScript time zone detection.
-  drupal_add_js('core/misc/timezone.js');
+  drupal_add_library('system', 'drupal.timezone');
   // We add these strings as settings because JavaScript translation does not
   // work on install time.
   drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))), 'setting');
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 504030e67a88746f185328f4636f03cab8f6a8e6..2550fe864155d17895d215de1c7dfc1f97a4938f 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -93,15 +93,6 @@ function drupal_theme_initialize() {
 
   // Themes can have alter functions, so reset the drupal_alter() cache.
   drupal_static_reset('drupal_alter');
-
-  // Provide the page with information about the theme that's used, so that a
-  // later Ajax request can be rendered using the same theme.
-  // @see ajax_base_page_theme()
-  $setting['ajaxPageState'] = array(
-    'theme' => $theme_key,
-    'theme_token' => drupal_get_token($theme_key),
-  );
-  drupal_add_js($setting, 'setting');
 }
 
 /**
@@ -1841,7 +1832,7 @@ function theme_table($variables) {
 
   // Add sticky headers, if applicable.
   if (count($header) && $sticky) {
-    drupal_add_js('core/misc/tableheader.js');
+    drupal_add_library('system', 'drupal.tableheader');
     // Add 'sticky-enabled' class to the table to identify it for JS.
     // This is needed to target tables constructed by this function.
     $attributes['class'][] = 'sticky-enabled';
@@ -2603,6 +2594,7 @@ function template_process_page(&$variables) {
  * @see html.tpl.php
  */
 function template_process_html(&$variables) {
+  drupal_add_library('system', 'html5shiv', TRUE);
   // Render page_top and page_bottom into top level variables.
   $variables['page_top'] = drupal_render($variables['page']['page_top']);
   $variables['page_bottom'] = drupal_render($variables['page']['page_bottom']);
diff --git a/core/modules/block/block.admin.inc b/core/modules/block/block.admin.inc
index aa018dad4efff24e8a48b36256a146d69e0c1807..848298f00d278d249ddd39947611c9b8ee9299ce 100644
--- a/core/modules/block/block.admin.inc
+++ b/core/modules/block/block.admin.inc
@@ -82,8 +82,8 @@ function block_admin_display_prepare_blocks($theme) {
 function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_regions = NULL) {
   $path = drupal_get_path('module', 'block');
   $form['#attached']['css'][] = $path . '/block.admin.css';
-  $form['#attached']['js'][] = 'core/misc/tableheader.js';
-  $form['#attached']['js'][] = $path . '/block.js';
+  $form['#attached']['library'][] = array('system', 'drupal.tableheader');
+  $form['#attached']['library'][] = array('block', 'drupal.block');
 
   // Get a list of block regions if one was not provided.
   if (!isset($block_regions)) {
@@ -346,7 +346,7 @@ function block_admin_configure($form, &$form_state, $module, $delta) {
   $form['visibility'] = array(
     '#type' => 'vertical_tabs',
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'block') . '/block.js'),
+      'library' => array(array('block', 'drupal.block')),
     ),
   );
 
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 2592137718b51159a59b3d9dbfc29ec2537646b8..0626c086ec29666c66b3723075948f43fe6a5432 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -1085,3 +1085,22 @@ function block_language_delete($language) {
     ->condition('langcode', $language->langcode)
     ->execute();
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function block_library_info() {
+  $libraries['drupal.block'] = array(
+    'title' => 'Block',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'block') . '/block.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index 6590aa85360c1062a6fb709367ef70b2d74ac161..7e7ca52c4f7a48e22ccf03fd4bae3bd4e3a5f08e 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -544,7 +544,7 @@ function _book_add_form_elements(&$form, &$form_state, Node $node) {
       'class' => array('book-outline-form'),
     ),
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'book') . '/book.js'),
+      'library' => array(array('book', 'drupal.book')),
     ),
     '#tree' => TRUE,
   );
@@ -1454,3 +1454,23 @@ function book_menu_subtree_data($link) {
 
   return $tree[$cid];
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function book_library_info() {
+  $libraries['drupal.book'] = array(
+    'title' => 'Book',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'book') . '/book.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.form'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index b2b67a799416083f15ed6fdc972557e6a9563811..d4ca6ca554ac6329877b89cad155da0e76fa834f 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -184,9 +184,8 @@ function color_scheme_form($complete_form, &$form_state, $theme) {
     '#options' => $color_sets,
     '#default_value' => $scheme_name,
     '#attached' => array(
-      // Add Farbtastic color picker.
       'library' => array(
-        array('system', 'farbtastic'),
+        array('color', 'drupal.color'),
       ),
       // Add custom CSS.
       'css' => array(
@@ -194,7 +193,6 @@ function color_scheme_form($complete_form, &$form_state, $theme) {
       ),
       // Add custom JavaScript.
       'js' => array(
-        $base . '/color.js',
         array(
           'data' => array(
             'color' => array(
@@ -246,6 +244,7 @@ function theme_color_scheme_form($variables) {
   $path = drupal_get_path('theme', $theme) . '/';
   drupal_add_css($path . $info['preview_css']);
 
+  // @todo Transform to add library.
   $preview_js_path = isset($info['preview_js']) ? $path . $info['preview_js'] : drupal_get_path('module', 'color') . '/' . 'preview.js';
   // Add the JS at a weight below color.js.
   drupal_add_js($preview_js_path, array('weight' => -1));
@@ -744,3 +743,38 @@ function _color_rgb2hsl($rgb) {
 
   return array($h, $s, $l);
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function color_library_info() {
+  $libraries['drupal.color'] = array(
+    'title' => 'Color',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'color') . '/color.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'jquery.once'),
+      array('system', 'jquery.farbtastic'),
+      array('color', 'drupal.color.preview'),
+    ),
+  );
+  $libraries['drupal.color.preview'] = array(
+    'title' => 'Color preview',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'color') . '/preview.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 8ab8070304a9996d3065ff01782a143341b22c19..f715cb3178ab749e2ef67110e7b82ecf9ec598e2 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1188,7 +1188,7 @@ function comment_form_node_type_form_alter(&$form, $form_state) {
         'class' => array('comment-node-type-settings-form'),
       ),
       '#attached' => array(
-        'js' => array(drupal_get_path('module', 'comment') . '/comment-node-form.js'),
+        'library' => array('comment', 'drupal.comment'),
       ),
     );
     // Unlike coment_form_node_form_alter(), all of these settings are applied
@@ -1266,8 +1266,8 @@ function comment_form_node_form_alter(&$form, $form_state) {
       'class' => array('comment-node-settings-form'),
     ),
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'comment') . '/comment-node-form.js'),
-     ),
+      'library' => array('comment', 'drupal.comment'),
+    ),
     '#weight' => 30,
   );
   $comment_count = isset($node->nid) ? db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField() : 0;
@@ -2142,3 +2142,23 @@ function comment_file_download_access($field, EntityInterface $entity, File $fil
     return FALSE;
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function comment_library_info() {
+  $libraries['drupal.comment'] = array(
+    'title' => 'Comment',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'comment') . '/comment-node-form.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.form'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/contextual/contextual.module b/core/modules/contextual/contextual.module
index a09d09ff5524db33b365366de39fc770a06c050b..37b3a21fe6b2589bd7458864a26de42c9f08e679 100644
--- a/core/modules/contextual/contextual.module
+++ b/core/modules/contextual/contextual.module
@@ -40,10 +40,10 @@ function contextual_permission() {
  */
 function contextual_library_info() {
   $path = drupal_get_path('module', 'contextual');
-  $libraries['contextual-links'] = array(
+  $libraries['drupal.contextual-links'] = array(
     'title' => 'Contextual Links',
     'website' => 'http://drupal.org/node/473268',
-    'version' => '1.0',
+    'version' => VERSION,
     'js' => array(
       $path . '/contextual.js' => array(),
     ),
@@ -51,7 +51,13 @@ function contextual_library_info() {
       $path . '/contextual.base.css' => array(),
       $path . '/contextual.theme.css' => array(),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'jquery.once'),
+    ),
   );
+
   return $libraries;
 }
 
@@ -68,7 +74,7 @@ function contextual_element_info() {
     '#attributes' => array('class' => array('contextual-links')),
     '#attached' => array(
       'library' => array(
-        array('contextual', 'contextual-links'),
+        array('contextual', 'drupal.contextual-links'),
       ),
     ),
   );
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index 5871be0816438d9989d9d8e63354cf92432095e2..0be7ffe735dda58b924f29a82e2fad6964b2cf86 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -640,8 +640,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save'));
 
-  $form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.admin.css';
-  $form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js';
+  $form['#attached']['library'][] = array('field_ui', 'drupal.field_ui');
 
   // Add settings for the update selects behavior.
   $js_fields = array();
@@ -1228,8 +1227,7 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save'));
 
-  $form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js';
-  $form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.admin.css';
+  $form['#attached']['library'][] = array('field_ui', 'drupal.field_ui');
 
   // Add tabledrag behavior.
   $form['#attached']['drupal_add_tabledrag'][] = array('field-display-overview', 'order', 'sibling', 'field-weight');
diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module
index 076cc233f9834efadb25d995d887f45c5d6fe82d..bde3f35ad11c8905f3ba8301401b77895641218b 100644
--- a/core/modules/field_ui/field_ui.module
+++ b/core/modules/field_ui/field_ui.module
@@ -380,3 +380,27 @@ function field_ui_form_node_type_form_submit($form, &$form_state) {
     $form_state['redirect'] = _field_ui_bundle_admin_path('node', $form_state['values']['type']) .'/fields';
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function field_ui_library_info() {
+  $libraries['drupal.field_ui'] = array(
+    'title' => 'Field UI',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'field_ui') . '/field_ui.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'field_ui') . '/field_ui.admin.css' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index 70314db5823cefd0b503baf69455145307e8ba43..cbc22465ec0c612f628953ead31a9d4a75919b49 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -37,7 +37,7 @@ function file_field_settings_form($field, $instance, $has_data) {
   $defaults = field_info_field_settings($field['type']);
   $settings = array_merge($defaults, $field['settings']);
 
-  $form['#attached']['js'][] = drupal_get_path('module', 'file') . '/file.js';
+  $form['#attached']['library'][] = array('file', 'drupal.file');
 
   $form['display_field'] = array(
     '#type' => 'checkbox',
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 32bbce99e38ed76d53ffd869599ed61fee25f944..8f06fc12117d46b80cc58f175c3e404a691f5284 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -78,8 +78,7 @@ function file_element_info() {
     '#size' => 22,
     '#extended' => FALSE,
     '#attached' => array(
-      'css' => array($file_path . '/file.admin.css'),
-      'js' => array($file_path . '/file.js'),
+      'library' => array(array('file','drupal.file')),
     ),
   );
   return $types;
@@ -1035,3 +1034,26 @@ function file_get_file_references(File $file, $field = NULL, $age = FIELD_LOAD_R
 /**
  * @} End of "defgroup file-module-api".
  */
+
+/**
+ * Implements hook_library_info().
+ */
+function file_library_info() {
+  $libraries['drupal.file'] = array(
+    'title' => 'File',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'file') . '/file.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'file') . '/file.admin.css'
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/filter/filter.admin.inc b/core/modules/filter/filter.admin.inc
index 4306b16c444c81855eaa7804ff014760f0ff5477..044fe5854d3dd3d07a4ebdfda190646ec69e534c 100644
--- a/core/modules/filter/filter.admin.inc
+++ b/core/modules/filter/filter.admin.inc
@@ -155,8 +155,7 @@ function filter_admin_format_form($form, &$form_state, $format) {
 
   $form['#format'] = $format;
   $form['#tree'] = TRUE;
-  $form['#attached']['js'][] = drupal_get_path('module', 'filter') . '/filter.admin.js';
-  $form['#attached']['css'][] = drupal_get_path('module', 'filter') . '/filter.admin.css';
+  $form['#attached']['library'][] = array('filter', 'drupal.filter.admin');
 
   $form['name'] = array(
     '#type' => 'textfield',
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 0afb47854d68b70c136733a0ea3f0208b5ca783d..53d40ecda321b8509d8c46bcac8b41da1e3bd63a 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -878,8 +878,7 @@ function filter_process_format($element) {
 
   // Turn original element into a text format wrapper.
   $path = drupal_get_path('module', 'filter');
-  $element['#attached']['js'][] = $path . '/filter.js';
-  $element['#attached']['css'][] = $path . '/filter.admin.css';
+  $element['#attached']['library'][] = array('filter', 'drupal.filter');
 
   // Setup child container for the text format widget.
   $element['format'] = array(
@@ -1764,3 +1763,42 @@ function _filter_html_escape_tips($filter, $format, $long = FALSE) {
 /**
  * @} End of "defgroup standard_filters".
  */
+
+/**
+ * Implements hook_library_info().
+ */
+function filter_library_info() {
+  $libraries['drupal.filter.admin'] = array(
+    'title' => 'Filter',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'filter') . '/filter.admin.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'filter') . '/filter.admin.css'
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'jquery.once'),
+      array('system', 'drupal.form'),
+    ),
+  );
+  $libraries['drupal.filter'] = array(
+    'title' => 'Filter',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'filter') . '/filter.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'filter') . '/filter.admin.css'
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'jquery.once'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleExportTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleExportTest.php
index 673867f708773a79effc618355db2c4304993710..bc7a69b3e0a16b9b49c509d58b98bd5eb83d7379 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleExportTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleExportTest.php
@@ -114,6 +114,10 @@ function testExportTranslation() {
    * Test exportation of translation template file.
    */
   function testExportTranslationTemplateFile() {
+    // Load an admin page with JavaScript so drupal_add_library() fires at least
+    // once and _locale_parse_js_file() gets to run at least once so that the
+    // locales_source table gets populated with something.
+    $this->drupalGet('admin/config/regional/language');
     // Get the translation template file.
     $this->drupalPost('admin/config/regional/translate/export', array(), t('Export'));
     // Ensure we have a translation file.
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index aec8978e2d77810bda9603905ffbfd1a6d3040c1..459d03d078074f4dbb47789c065c3f61e774486e 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -374,7 +374,7 @@ function locale_js_alter(&$javascript) {
   $files = $new_files = FALSE;
 
   foreach ($javascript as $item) {
-    if ($item['type'] == 'file') {
+    if (isset($item['type']) && $item['type'] == 'file') {
       $files = TRUE;
       $filepath = $item['data'];
       if (!in_array($filepath, $parsed)) {
@@ -420,6 +420,38 @@ function locale_js_alter(&$javascript) {
   }
 }
 
+/**
+ * Implements hook_library_info().
+ */
+function locale_library_info() {
+  $libraries['drupal.locale.admin'] = array(
+    'title' => 'Locale',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'locale') . '/locale.admin.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'jquery.once'),
+    ),
+  );
+  $libraries['drupal.locale.datepicker'] = array(
+    'title' => 'Locale Datepicker UI',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'locale') . '/locale.datepicker.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+    ),
+  );
+
+  return $libraries;
+}
+
 /**
  * Implement hook_library_info_alter().
  *
@@ -431,8 +463,7 @@ function locale_library_info_alter(&$libraries, $module) {
     // locale.datepicker.js should be added in the JS_LIBRARY group, so that
     // this attach behavior will execute early. JS_LIBRARY is the default for
     // hook_library_info_alter(), thus does not have to be specified explicitly.
-    $datepicker = drupal_get_path('module', 'locale') . '/locale.datepicker.js';
-    $libraries['jquery.ui.datepicker']['js'][$datepicker] = array();
+    $libraries['jquery.ui.datepicker']['dependencies'][] = array('locale', 'drupal.locale.datepicker');
     $libraries['jquery.ui.datepicker']['js'][] = array(
       'data' => array(
         'jquery' => array(
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index 539c382d9fa26825a9da5b34cdf7f9147eeb69a5..5fdba76ca8318eea3f90e92672793127209a5c7a 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -255,9 +255,7 @@ function locale_translate_edit_form($form, &$form_state) {
   $form['#attached']['css'] = array(
     $path . '/locale.admin.css',
   );
-  $form['#attached']['js'] = array(
-    $path . '/locale.admin.js',
-  );
+  $form['#attached']['library'][] = array('locale', 'drupal.locale.admin');
 
   $form['langcode'] = array(
     '#type' => 'value',
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 653c17f8804eb13718c09841a488ff217734b86f..189abccf6607cbf43cbcaf9057fe66a67809f67d 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -650,7 +650,7 @@ function menu_form_node_form_alter(&$form, $form_state) {
     '#collapsed' => !$link['link_title'],
     '#group' => 'additional_settings',
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'menu') . '/menu.js'),
+      'library' => array(array('menu', 'drupal.menu')),
     ),
     '#tree' => TRUE,
     '#weight' => -2,
@@ -755,7 +755,7 @@ function menu_form_node_type_form_alter(&$form, $form_state) {
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'menu') . '/menu.admin.js'),
+      'library' => array(array('menu', 'drupal.menu.admin')),
     ),
     '#group' => 'additional_settings',
   );
@@ -819,3 +819,34 @@ function menu_preprocess_block(&$variables) {
     $variables['attributes']['role'] = 'navigation';
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function menu_library_info() {
+  $libraries['drupal.menu'] = array(
+    'title' => 'Menu',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'menu') . '/menu.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.form'),
+    ),
+  );
+  $libraries['drupal.menu.admin'] = array(
+    'title' => 'Menu admin',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'menu') . '/menu.admin.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/node/content_types.inc b/core/modules/node/content_types.inc
index 88495f466b17ef4e32e0b095a15b2b559953fe6d..355a022bed25ff6057b97c4035f056fda594c9d2 100644
--- a/core/modules/node/content_types.inc
+++ b/core/modules/node/content_types.inc
@@ -127,7 +127,7 @@ function node_type_form($form, &$form_state, $type = NULL) {
   $form['additional_settings'] = array(
     '#type' => 'vertical_tabs',
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'node') . '/content_types.js'),
+      'library' => array(array('node', 'drupal.content_types')),
     ),
   );
 
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index 0bf8a9140da0ac6b5cf77f2ad91a98e90920d99f..5cbe4efefe70ebb41015c2e47703aef2eb11060b 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -222,7 +222,7 @@ function node_filter_form() {
     $form['filters']['status']['actions']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
   }
 
-  drupal_add_js('core/misc/form.js');
+  $form['#attached']['library'][] = array('system', 'drupal.form');
 
   return $form;
 }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index f3849e0be26957918e4ee71375e0c702e61a2489..943afaa3232e0505d901b2a42af16347b243819a 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -3996,3 +3996,36 @@ function node_language_delete($language) {
     ->condition('langcode', $language->langcode)
     ->execute();
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function node_library_info() {
+  $libraries['drupal.node'] = array(
+    'title' => 'Node',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'node') . '/node.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'drupal.form'),
+    ),
+  );
+  $libraries['drupal.content_types'] = array(
+    'title' => 'Content types',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'node') . '/content_types.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.form'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module
index 51d3f5cdf6c28b09f386c566f8dc32d174a60ba4..eafb0b0765d354137d8244782736a146b366f9e7 100644
--- a/core/modules/openid/openid.module
+++ b/core/modules/openid/openid.module
@@ -134,9 +134,7 @@ function openid_form_user_login_alter(&$form, &$form_state) {
 }
 
 function _openid_user_login_form_alter(&$form, &$form_state) {
-  $form['#attached']['css'][] = drupal_get_path('module', 'openid') . '/openid.css';
-  $form['#attached']['js'][] = drupal_get_path('module', 'openid') . '/openid.js';
-  $form['#attached']['library'][] = array('system', 'jquery.cookie');
+  $form['#attached']['library'][] = array('openid', 'drupal.openid');
   if (!empty($form_state['input']['openid_identifier'])) {
     $form['name']['#required'] = FALSE;
     $form['pass']['#required'] = FALSE;
@@ -1076,3 +1074,25 @@ function openid_cron() {
     ->condition('expires', REQUEST_TIME, '<')
     ->execute();
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function openid_library_info() {
+  $libraries['openid'] = array(
+    'title' => 'OpenID',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'openid') . '/openid.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'openid') . '/openid.css' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'drupal'),
+      array('system', 'jquery.cookie')
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module
index 3aaed7d9302e33a41bbd5804fe0b42d20e5f9b76..7a07b709a7e9dd6e375d14937d651f24721aa0b5 100644
--- a/core/modules/overlay/overlay.module
+++ b/core/modules/overlay/overlay.module
@@ -200,7 +200,7 @@ function overlay_library_info() {
   $module_path = drupal_get_path('module', 'overlay');
 
   // Overlay parent.
-  $libraries['parent'] = array(
+  $libraries['drupal.overlay.parent'] = array(
     'title' => 'Overlay: Parent',
     'website' => 'http://drupal.org/documentation/modules/overlay',
     'version' => '1.0',
@@ -211,12 +211,15 @@ function overlay_library_info() {
       $module_path . '/overlay-parent.css' => array(),
     ),
     'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
       array('system', 'jquery.ui.core'),
       array('system', 'jquery.bbq'),
     ),
   );
   // Overlay child.
-  $libraries['child'] = array(
+  $libraries['drupal.overlay.child'] = array(
     'title' => 'Overlay: Child',
     'website' => 'http://drupal.org/documentation/modules/overlay',
     'version' => '1.0',
@@ -226,6 +229,12 @@ function overlay_library_info() {
     'css' => array(
       $module_path . '/overlay-child.css' => array(),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+    ),
   );
 
   return $libraries;
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 2baa603780e05f5f463b53b6c09bcd264b5ced0e..02a04904546e5bf6a0435bbabf445002c8f391f2 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -129,7 +129,7 @@ function path_form_node_form_alter(&$form, $form_state) {
       'class' => array('path-form'),
     ),
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'path') . '/path.js'),
+      'library' => array(array('path', 'drupal.path')),
     ),
     '#access' => user_access('create url aliases') || user_access('administer url aliases'),
     '#weight' => 30,
@@ -314,3 +314,23 @@ function path_taxonomy_term_delete(Term $term) {
   // Delete all aliases associated with this term.
   path_delete(array('source' => 'taxonomy/term/' . $term->tid));
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function path_library_info() {
+  $libraries['drupal.path'] = array(
+    'title' => 'Path',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'path') . '/path.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.form'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/shortcut/shortcut.admin.inc b/core/modules/shortcut/shortcut.admin.inc
index 3345c5941379e10ac812a573aaad3006e167776d..26bdc36cff9d9d025669ee42839ce8d353135f40 100644
--- a/core/modules/shortcut/shortcut.admin.inc
+++ b/core/modules/shortcut/shortcut.admin.inc
@@ -73,7 +73,7 @@ function shortcut_set_switch($form, &$form_state, $account = NULL) {
     }
 
     $form['#attached'] = array(
-      'js' => array(drupal_get_path('module', 'shortcut') . '/shortcut.admin.js'),
+      'library' => array(array('shortcut', 'drupal.shortcut.admin')),
     );
 
     $form['actions'] = array('#type' => 'actions');
diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module
index 27eb8c259e05ab61775ce72cb4423920b3db6d17..a548fc2410cd1a3eb0a58386eb3c0ea37400d881 100644
--- a/core/modules/shortcut/shortcut.module
+++ b/core/modules/shortcut/shortcut.module
@@ -766,3 +766,21 @@ function shortcut_set_title($shortcut_set) {
   return $shortcut_set->title;
 }
 
+/**
+ * Implements hook_library_info().
+ */
+function shortcut_library_info() {
+  $libraries['drupal.shortcut.admin'] = array(
+    'title' => 'Shortcut',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'shortcut') . '/shortcut.admin.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index d31a2e386cabcebc20ef1c237412abc5156e1d50..d4ef37bf8c53f8ced20e498eef393030493153d6 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -566,3 +566,28 @@ function simpletest_mail_alter(&$message) {
     $message['send'] = FALSE;
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function simpletest_library_info() {
+  $libraries['drupal.simpletest'] = array(
+    'title' => 'Simpletest',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'simpletest') . '/simpletest.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'simpletest') . '/simpletest.css' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+      array('system', 'drupal.tableselect'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/simpletest/simpletest.pages.inc b/core/modules/simpletest/simpletest.pages.inc
index a98b445548d61dea62675db92b438730131866d4..48cb3a13e09ab35f15ab2039f3c92ef9378a5b01 100644
--- a/core/modules/simpletest/simpletest.pages.inc
+++ b/core/modules/simpletest/simpletest.pages.inc
@@ -68,9 +68,7 @@ function simpletest_test_form($form) {
 function theme_simpletest_test_table($variables) {
   $table = $variables['table'];
 
-  drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
-  drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js');
-  drupal_add_js('core/misc/tableselect.js');
+  drupal_add_library('simpletest', 'drupal.simpletest');
 
   // Create header for test selection table.
   $header = array(
diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module
index 35f625a76d4b388221fb3d33c6e8e8c081d089f1..c07a1c818a271d4db840272a3711cc3da3211251 100644
--- a/core/modules/statistics/statistics.module
+++ b/core/modules/statistics/statistics.module
@@ -103,11 +103,7 @@ function statistics_permission() {
  */
 function statistics_node_view(Node $node, $view_mode) {
   if (!empty($node->nid) && $view_mode == 'full') {
-    $node->content['#attached']['js'] = array(
-      drupal_get_path('module', 'statistics') . '/statistics.js' => array(
-        'scope' => 'footer'
-      ),
-    );
+    $node->content['#attached']['library'][] = array('statistics', 'drupal.statistics');
     $settings = array('nid' => $node->nid);
     $node->content['#attached']['js'][] = array(
       'data' => array('statistics' => $settings),
@@ -462,3 +458,25 @@ function statistics_preprocess_block(&$variables) {
     $variables['attributes']['role'] = 'navigation';
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function statistics_library_info() {
+  $libraries['drupal.statistics'] = array(
+    'title' => 'Statistics',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'statistics') . '/statistics.js' => array(
+        'scope' => 'footer'
+      ),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
index b43e3fb17856f822db2ff40f399ff9486ec55f53..7d8eb08acb9ca992e98805178ab622881afe9932 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
@@ -68,13 +68,7 @@ function testDefault() {
    */
   function testAddFile() {
     $javascript = drupal_add_js('core/misc/collapse.js');
-    $this->assertTrue(array_key_exists('core/misc/jquery.js', $javascript), t('jQuery is added when a file is added.'));
-    $this->assertTrue(array_key_exists('core/misc/drupal.js', $javascript), t('Drupal.js is added when file is added.'));
-    $this->assertTrue(array_key_exists('core/misc/html5.js', $javascript), t('html5.js is added when file is added.'));
     $this->assertTrue(array_key_exists('core/misc/collapse.js', $javascript), t('JavaScript files are correctly added.'));
-    $this->assertEqual(base_path(), $javascript['settings']['data'][0]['basePath'], t('Base path JavaScript setting is correctly set.'));
-    $this->assertIdentical($GLOBALS['script_path'], $javascript['settings']['data'][1]['scriptPath'], t('Script path JavaScript setting is correctly set.'));
-    $this->assertIdentical('', $javascript['settings']['data'][2]['pathPrefix'], t('Path prefix JavaScript setting is correctly set.'));
   }
 
   /**
@@ -82,8 +76,10 @@ function testAddFile() {
    */
   function testAddSetting() {
     // Add a file in order to test default settings.
-    $javascript = drupal_add_js('core/misc/collapse.js');
-    $last_settings = end($javascript['settings']['data']);
+    drupal_add_library('system', 'drupal.settings');
+    drupal_add_js(array('dummy' => 'value'), 'setting');
+    $javascript = drupal_add_js();
+    $last_settings = reset($javascript['settings']['data']);
     $this->assertTrue($last_settings['currentPath'], 'The current path JavaScript setting is set correctly.');
 
     $javascript = drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting');
@@ -107,6 +103,7 @@ function testAddExternal() {
   function testAsyncAttribute() {
     $default_query_string = variable_get('css_js_query_string', '0');
 
+    drupal_add_library('system', 'drupal');
     drupal_add_js('http://example.com/script.js', array('async' => TRUE));
     drupal_add_js('core/misc/collapse.js', array('async' => TRUE));
     $javascript = drupal_get_js();
@@ -124,6 +121,7 @@ function testAsyncAttribute() {
   function testDeferAttribute() {
     $default_query_string = variable_get('css_js_query_string', '0');
 
+    drupal_add_library('system', 'drupal');
     drupal_add_js('http://example.com/script.js', array('defer' => TRUE));
     drupal_add_js('core/misc/collapse.js', array('defer' => TRUE));
     $javascript = drupal_get_js();
@@ -139,6 +137,7 @@ function testDeferAttribute() {
    * Test drupal_get_js() for JavaScript settings.
    */
   function testHeaderSetting() {
+    drupal_add_library('system', 'drupal.settings');
     // Only the second of these two entries should appear in Drupal.settings.
     drupal_add_js(array('commonTest' => 'commonTestShouldNotAppear'), 'setting');
     drupal_add_js(array('commonTest' => 'commonTestShouldAppear'), 'setting');
@@ -183,6 +182,7 @@ function testHeaderSetting() {
    * Test to see if resetting the JavaScript empties the cache.
    */
   function testReset() {
+    drupal_add_library('system', 'drupal');
     drupal_add_js('core/misc/collapse.js');
     drupal_static_reset('drupal_add_js');
     $this->assertEqual(array(), drupal_add_js(), t('Resetting the JavaScript correctly empties the cache.'));
@@ -192,6 +192,7 @@ function testReset() {
    * Test adding inline scripts.
    */
   function testAddInline() {
+    drupal_add_library('system', 'drupal');
     $inline = 'jQuery(function () { });';
     $javascript = drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer'));
     $this->assertTrue(array_key_exists('core/misc/jquery.js', $javascript), t('jQuery is added when inline scripts are added.'));
@@ -203,6 +204,7 @@ function testAddInline() {
    * Test rendering an external JavaScript file.
    */
   function testRenderExternal() {
+    drupal_add_library('system', 'drupal');
     $external = 'http://example.com/example.js';
     drupal_add_js($external, 'external');
     $javascript = drupal_get_js();
@@ -214,6 +216,7 @@ function testRenderExternal() {
    * Test drupal_get_js() with a footer scope.
    */
   function testFooterHTML() {
+    drupal_add_library('system', 'drupal');
     $inline = 'jQuery(function () { });';
     drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer'));
     $javascript = drupal_get_js('footer');
@@ -224,6 +227,7 @@ function testFooterHTML() {
    * Test drupal_add_js() sets preproccess to false when cache is set to false.
    */
   function testNoCache() {
+    drupal_add_library('system', 'drupal');
     $javascript = drupal_add_js('core/misc/collapse.js', array('cache' => FALSE));
     $this->assertFalse($javascript['core/misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.'));
   }
@@ -232,6 +236,7 @@ function testNoCache() {
    * Test adding a JavaScript file with a different group.
    */
   function testDifferentGroup() {
+    drupal_add_library('system', 'drupal');
     $javascript = drupal_add_js('core/misc/collapse.js', array('group' => JS_THEME));
     $this->assertEqual($javascript['core/misc/collapse.js']['group'], JS_THEME, t('Adding a JavaScript file with a different group caches the given group.'));
   }
@@ -252,6 +257,7 @@ function testDifferentWeight() {
   function testBrowserConditionalComments() {
     $default_query_string = variable_get('css_js_query_string', '0');
 
+    drupal_add_library('system', 'drupal');
     drupal_add_js('core/misc/collapse.js', array('browsers' => array('IE' => 'lte IE 8', '!IE' => FALSE)));
     drupal_add_js('jQuery(function () { });', array('type' => 'inline', 'browsers' => array('IE' => FALSE)));
     $javascript = drupal_get_js();
@@ -267,6 +273,7 @@ function testBrowserConditionalComments() {
    * Test JavaScript versioning.
    */
   function testVersionQueryString() {
+    drupal_add_library('system', 'drupal');
     drupal_add_js('core/misc/collapse.js', array('version' => 'foo'));
     drupal_add_js('core/misc/ajax.js', array('version' => 'bar'));
     $javascript = drupal_get_js();
@@ -283,6 +290,7 @@ function testAggregation() {
     // ahead of ones without. The order of JavaScript execution must be the
     // same regardless of whether aggregation is enabled, so ensure this
     // expected order, first with aggregation off.
+    drupal_add_library('system', 'drupal');
     drupal_add_js('core/misc/ajax.js');
     drupal_add_js('core/misc/collapse.js', array('every_page' => TRUE));
     drupal_add_js('core/misc/autocomplete.js');
@@ -302,6 +310,7 @@ function testAggregation() {
     $config = config('system.performance');
     $config->set('preprocess.js', 1);
     $config->save();
+    drupal_add_library('system', 'drupal');
     drupal_add_js('core/misc/ajax.js');
     drupal_add_js('core/misc/collapse.js', array('every_page' => TRUE));
     drupal_add_js('core/misc/autocomplete.js');
@@ -312,7 +321,7 @@ function testAggregation() {
       '<script type="text/javascript" src="' . file_create_url(drupal_build_js_cache(array('core/misc/collapse.js' => $js_items['core/misc/collapse.js'], 'core/misc/batch.js' => $js_items['core/misc/batch.js']))) . '"></script>',
       '<script type="text/javascript" src="' . file_create_url(drupal_build_js_cache(array('core/misc/ajax.js' => $js_items['core/misc/ajax.js'], 'core/misc/autocomplete.js' => $js_items['core/misc/autocomplete.js']))) . '"></script>',
     ));
-    $this->assertTrue(strpos($javascript, $expected) > 0, t('JavaScript is aggregated in the expected groups and order.'));
+    $this->assertTrue(strpos($javascript, $expected) !== FALSE, t('JavaScript is aggregated in the expected groups and order.'));
   }
 
   /**
@@ -324,6 +333,7 @@ function testAggregationOrder() {
     drupal_static_reset('drupal_add_js');
 
     // Add two JavaScript files to the current request and build the cache.
+    drupal_add_library('system', 'drupal');
     drupal_add_js('core/misc/ajax.js');
     drupal_add_js('core/misc/autocomplete.js');
 
@@ -340,6 +350,7 @@ function testAggregationOrder() {
     // Reset variables and add a file in a different scope first.
     variable_del('drupal_js_cache_files');
     drupal_static_reset('drupal_add_js');
+    drupal_add_library('system', 'drupal');
     drupal_add_js('some/custom/javascript_file.js', array('scope' => 'footer'));
     drupal_add_js('core/misc/ajax.js');
     drupal_add_js('core/misc/autocomplete.js');
@@ -406,6 +417,7 @@ function testRenderDifferentWeight() {
     // JavaScript files are sorted first by group, then by the 'every_page'
     // flag, then by weight (see drupal_sort_css_js()), so to test the effect of
     // weight, we need the other two options to be the same.
+    drupal_add_library('system', 'jquery');
     drupal_add_js('core/misc/collapse.js', array('group' => JS_LIBRARY, 'every_page' => TRUE, 'weight' => -21));
     $javascript = drupal_get_js();
     $this->assertTrue(strpos($javascript, 'core/misc/collapse.js') < strpos($javascript, 'core/misc/jquery.js'), t('Rendering a JavaScript file above jQuery.'));
@@ -432,7 +444,7 @@ function testAlter() {
    * Adds a library to the page and tests for both its JavaScript and its CSS.
    */
   function testLibraryRender() {
-    $result = drupal_add_library('system', 'farbtastic');
+    $result = drupal_add_library('system', 'jquery.farbtastic');
     $this->assertTrue($result !== FALSE, t('Library was added without errors.'));
     $scripts = drupal_get_js();
     $styles = drupal_get_css();
@@ -447,11 +459,11 @@ function testLibraryRender() {
    */
   function testLibraryAlter() {
     // Verify that common_test altered the title of Farbtastic.
-    $library = drupal_get_library('system', 'farbtastic');
+    $library = drupal_get_library('system', 'jquery.farbtastic');
     $this->assertEqual($library['title'], 'Farbtastic: Altered Library', t('Registered libraries were altered.'));
 
     // common_test_library_info_alter() also added a dependency on jQuery Form.
-    drupal_add_library('system', 'farbtastic');
+    drupal_add_library('system', 'jquery.farbtastic');
     $scripts = drupal_get_js();
     $this->assertTrue(strpos($scripts, 'core/misc/jquery.form.js'), t('Altered library dependencies are added to the page.'));
   }
@@ -462,7 +474,7 @@ function testLibraryAlter() {
    * @see common_test_library_info()
    */
   function testLibraryNameConflicts() {
-    $farbtastic = drupal_get_library('common_test', 'farbtastic');
+    $farbtastic = drupal_get_library('common_test', 'jquery.farbtastic');
     $this->assertEqual($farbtastic['title'], 'Custom Farbtastic Library', t('Alternative libraries can be added to the page.'));
   }
 
@@ -484,7 +496,7 @@ function testLibraryUnknown() {
    * Tests the addition of libraries through the #attached['library'] property.
    */
   function testAttachedLibrary() {
-    $element['#attached']['library'][] = array('system', 'farbtastic');
+    $element['#attached']['library'][] = array('system', 'jquery.farbtastic');
     drupal_render($element);
     $scripts = drupal_get_js();
     $this->assertTrue(strpos($scripts, 'core/misc/farbtastic/farbtastic.js'), t('The attached_library property adds the additional libraries.'));
@@ -496,14 +508,14 @@ function testAttachedLibrary() {
   function testGetLibrary() {
     // Retrieve all libraries registered by a module.
     $libraries = drupal_get_library('common_test');
-    $this->assertTrue(isset($libraries['farbtastic']), t('Retrieved all module libraries.'));
+    $this->assertTrue(isset($libraries['jquery.farbtastic']), t('Retrieved all module libraries.'));
     // Retrieve all libraries for a module not implementing hook_library_info().
-    // Note: This test installs Locale module.
-    $libraries = drupal_get_library('locale');
+    // Note: This test installs language module.
+    $libraries = drupal_get_library('language');
     $this->assertEqual($libraries, array(), t('Retrieving libraries from a module not implementing hook_library_info() returns an emtpy array.'));
 
     // Retrieve a specific library by module and name.
-    $farbtastic = drupal_get_library('common_test', 'farbtastic');
+    $farbtastic = drupal_get_library('common_test', 'jquery.farbtastic');
     $this->assertEqual($farbtastic['version'], '5.3', t('Retrieved a single library.'));
     // Retrieve a non-existing library by module and name.
     $farbtastic = drupal_get_library('common_test', 'foo');
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 72c50d4caa112ebc4298811e0dfba63b4a37fa89..3ccb13bcf9fa548831b8d37dab93e282457ca760 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -1696,7 +1696,7 @@ function system_logging_settings_submit($form, &$form_state) {
  * @see system_performance_settings_submit().
  */
 function system_performance_settings($form, &$form_state) {
-  drupal_add_js(drupal_get_path('module', 'system') . '/system.js');
+  drupal_add_library('system', 'drupal.system');
   $config = config('system.performance');
 
   $form['clear_cache'] = array(
@@ -2886,7 +2886,8 @@ function system_configure_date_formats_form($form, &$form_state, $dfid = 0) {
     '#default_value' => ($dfid ? $format->format : ''),
     '#field_suffix' => ' <small id="edit-date-format-suffix">' . $now . '</small>',
     '#attached' => array(
-      'js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings),
+      'library' => array(array('system', 'drupal.system')),
+      'js' => array($js_settings),
     ),
     '#required' => TRUE,
   );
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 69a1f62c60e0087f8598433fb139247777f91c13..c151ef0bdf82150bd82e9a3768c91ded5da39c13 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1216,6 +1216,28 @@ function _system_batch_theme() {
  * Implements hook_library_info().
  */
 function system_library_info() {
+  // Drupal-specific JavaScript.
+  $libraries['drupal'] = array(
+    'title' => 'Drupal',
+    'version' => VERSION,
+    'js' => array(
+      'core/misc/drupal.js' => array('group' => JS_LIBRARY, 'weight' => -18),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+    ),
+  );
+
+  // Drupal settings.
+  $libraries['drupal.settings'] = array(
+    'title' => 'Drupal Settings',
+    'version' => VERSION,
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+    ),
+  );
+
   // Drupal's Ajax framework.
   $libraries['drupal.ajax'] = array(
     'title' => 'Drupal AJAX',
@@ -1225,6 +1247,9 @@ function system_library_info() {
       'core/misc/ajax.js' => array('group' => JS_LIBRARY, 'weight' => 2),
     ),
     'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
       array('system', 'drupal.progress'),
     ),
   );
@@ -1237,7 +1262,11 @@ function system_library_info() {
       'core/misc/batch.js' => array('group' => JS_DEFAULT, 'cache' => FALSE),
     ),
     'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
       array('system', 'drupal.progress'),
+      array('system', 'jquery.once'),
     ),
   );
 
@@ -1248,6 +1277,11 @@ function system_library_info() {
     'js' => array(
       'core/misc/progress.js' => array('group' => JS_DEFAULT),
     ),
+    'dependencies' => array(
+      array('system', 'drupal'),
+      array('system', 'jquery'),
+      array('system', 'drupal.settings'),
+    ),
   );
 
   // Drupal's form library.
@@ -1257,6 +1291,12 @@ function system_library_info() {
     'js' => array(
       'core/misc/form.js' => array('group' => JS_LIBRARY, 'weight' => 1),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'jquery.cookie'),
+      array('system', 'jquery.once'),
+    ),
   );
 
   // Drupal's states library.
@@ -1266,6 +1306,12 @@ function system_library_info() {
     'js' => array(
       'core/misc/states.js' => array('group' => JS_LIBRARY, 'weight' => 1),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+    ),
   );
 
   // Drupal's tabledrag library.
@@ -1276,6 +1322,10 @@ function system_library_info() {
       'core/misc/tabledrag.js' => array('group' => JS_LIBRARY, 'weight' => -1),
     ),
     'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
       array('system', 'jquery.cookie'),
     ),
   );
@@ -1288,6 +1338,8 @@ function system_library_info() {
       'core/misc/collapse.js' => array('group' => JS_DEFAULT),
     ),
     'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
       // collapse.js relies on drupalGetSummary in form.js
       array('system', 'drupal.form'),
     ),
@@ -1300,6 +1352,11 @@ function system_library_info() {
     'js' => array(
       'core/misc/autocomplete.js' => array('group' => JS_DEFAULT),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.ajax'),
+    ),
   );
 
   // jQuery.
@@ -1320,6 +1377,9 @@ function system_library_info() {
     'js' => array(
       'core/misc/jquery.once.js' => array('group' => JS_LIBRARY, 'weight' => -19),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+    ),
   );
 
   // jQuery Form Plugin.
@@ -1331,6 +1391,7 @@ function system_library_info() {
       'core/misc/jquery.form.js' => array(),
     ),
     'dependencies' => array(
+      array('system', 'jquery'),
       array('system', 'jquery.cookie'),
     ),
   );
@@ -1343,6 +1404,9 @@ function system_library_info() {
     'js' => array(
       'core/misc/jquery.ba-bbq.js' => array(),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+    ),
   );
 
   // Vertical Tabs.
@@ -1357,13 +1421,16 @@ function system_library_info() {
       'core/misc/vertical-tabs.css' => array(),
     ),
     'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
       // Vertical tabs relies on drupalGetSummary in form.js
       array('system', 'drupal.form'),
     ),
   );
 
   // Farbtastic.
-  $libraries['farbtastic'] = array(
+  $libraries['jquery.farbtastic'] = array(
     'title' => 'Farbtastic',
     'website' => 'http://code.google.com/p/farbtastic/',
     'version' => '1.2',
@@ -1401,6 +1468,9 @@ function system_library_info() {
       'core/misc/ui/themes/base/jquery.ui.core.css' => array(),
       'core/misc/ui/themes/base/jquery.ui.theme.css' => array(),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+    ),
   );
   $libraries['jquery.ui.accordion'] = array(
     'title' => 'jQuery UI: Accordion',
@@ -1835,6 +1905,83 @@ function system_library_info() {
     'js' => array(
       'core/misc/ui/external/jquery.cookie.js' => array(),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+    ),
+  );
+
+  $libraries['drupal.tableselect'] = array(
+    'title' => 'Tableselect',
+    'version' => VERSION,
+    'js' => array(
+      'core/misc/tableselect.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'drupal'),
+      array('system', 'jquery'),
+    ),
+  );
+  $libraries['drupal.tableheader'] = array(
+    'title' => 'Table header',
+    'version' => VERSION,
+    'js' => array(
+      'core/misc/tableheader.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+    ),
+  );
+  $libraries['drupal.timezone'] = array(
+    'title' => 'Timezone',
+    'version' => VERSION,
+    'js' => array(
+      'core/misc/timezone.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+    ),
+  );
+  $libraries['drupal.machine-name'] = array(
+    'title' => 'Machine name',
+    'version' => VERSION,
+    'js' => array(
+      'core/misc/machine-name.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+    ),
+  );
+
+  $libraries['drupal.system'] = array(
+    'title' => 'System',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'system') . '/system.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+    ),
+  );
+  $libraries['drupal.system.cron'] = array(
+    'title' => 'System cron',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'system') . '/system.cron.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+    ),
   );
 
   return $libraries;
@@ -2276,7 +2423,7 @@ function system_user_timezone(&$form, &$form_state) {
   if (!isset($account->timezone) && $account->uid == $user->uid && empty($form_state['input']['timezone'])) {
     $form['timezone']['#description'] = t('Your time zone setting will be automatically detected if possible. Confirm the selection and click save.');
     $form['timezone']['timezone']['#attributes'] = array('class' => array('timezone-detect'));
-    drupal_add_js('core/misc/timezone.js');
+    drupal_add_library('system', 'drupal.timezone');
   }
 }
 
diff --git a/core/modules/system/tests/modules/common_test/common_test.module b/core/modules/system/tests/modules/common_test/common_test.module
index 187fee55b06d2ad5f15a2b19cc0d619ad88171ab..dcfb0129bb9691adfe017c6102a2500c66cbc0cc 100644
--- a/core/modules/system/tests/modules/common_test/common_test.module
+++ b/core/modules/system/tests/modules/common_test/common_test.module
@@ -237,11 +237,11 @@ function theme_common_test_foo($variables) {
  * Implements hook_library_info_alter().
  */
 function common_test_library_info_alter(&$libraries, $module) {
-  if ($module == 'system' && isset($libraries['farbtastic'])) {
+  if ($module == 'system' && isset($libraries['jquery.farbtastic'])) {
     // Change the title of Farbtastic to "Farbtastic: Altered Library".
-    $libraries['farbtastic']['title'] = 'Farbtastic: Altered Library';
+    $libraries['jquery.farbtastic']['title'] = 'Farbtastic: Altered Library';
     // Make Farbtastic depend on jQuery Form to test library dependencies.
-    $libraries['farbtastic']['dependencies'][] = array('system', 'jquery.form');
+    $libraries['jquery.farbtastic']['dependencies'][] = array('system', 'jquery.form');
   }
 }
 
@@ -251,7 +251,7 @@ function common_test_library_info_alter(&$libraries, $module) {
  * Adds Farbtastic in a different version.
  */
 function common_test_library_info() {
-  $libraries['farbtastic'] = array(
+  $libraries['jquery.farbtastic'] = array(
     'title' => 'Custom Farbtastic Library',
     'website' => 'http://code.google.com/p/farbtastic/',
     'version' => '5.3',
@@ -261,6 +261,9 @@ function common_test_library_info() {
     'css' => array(
       'core/misc/farbtastic/farbtastic.css' => array(),
     ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+    ),
   );
   return $libraries;
 }
@@ -269,6 +272,8 @@ function common_test_library_info() {
  * Adds a JavaScript file and a CSS file with a query string appended.
  */
 function common_test_js_and_css_querystring() {
+   drupal_add_library('system', 'drupal.settings');
+   drupal_add_js(array('dummy' => 'value'), 'setting');
    drupal_add_js(drupal_get_path('module', 'node') . '/node.js');
    drupal_add_css(drupal_get_path('module', 'node') . '/node.admin.css');
    // A relative URI may have a query string.
diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc
index 163c0e71c0235448bd2edd6bdec8a7e789828f72..ecef0b5873768a9625748b17e4972aeaa6bf7fbc 100644
--- a/core/modules/taxonomy/taxonomy.admin.inc
+++ b/core/modules/taxonomy/taxonomy.admin.inc
@@ -447,9 +447,8 @@ function theme_taxonomy_overview_terms($variables) {
   if ($form['#parent_fields']) {
     drupal_add_tabledrag('taxonomy', 'match', 'parent', 'term-parent', 'term-parent', 'term-id', FALSE);
     drupal_add_tabledrag('taxonomy', 'depth', 'group', 'term-depth', NULL, NULL, FALSE);
-    drupal_add_js(drupal_get_path('module', 'taxonomy') . '/taxonomy.js');
+    drupal_add_library('taxonomy', 'drupal.taxonomy');
     drupal_add_js(array('taxonomy' => array('backStep' => $back_step, 'forwardStep' => $forward_step)), 'setting');
-    drupal_add_css(drupal_get_path('module', 'taxonomy') . '/taxonomy.css');
   }
   drupal_add_tabledrag('taxonomy', 'order', 'sibling', 'term-weight');
 
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 4894cf133a5a59c5161e636ee7e932e9ad6daed5..aead43dbbba0042d0da159181eefa5b813651326 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -1697,3 +1697,27 @@ function taxonomy_entity_query_alter($query) {
     unset($conditions['bundle']);
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function taxonomy_library_info() {
+  $libraries['drupal.taxonomy'] = array(
+    'title' => 'Taxonomy',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'taxonomy') . '/taxonomy.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'taxonomy') . '/taxonomy.css' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'drupal.tabledrag'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module
index 5831d46bfd7771eeaabb3005ff7a9a104c6dc01b..fa4dd6ffedec7ab2455cb99dc024f96609f93f13 100644
--- a/core/modules/toolbar/toolbar.module
+++ b/core/modules/toolbar/toolbar.module
@@ -188,17 +188,12 @@ function toolbar_system_info_alter(&$info, $file, $type) {
 function toolbar_view() {
   global $user;
 
-  $module_path = drupal_get_path('module', 'toolbar');
   $build = array(
     '#theme' => 'toolbar',
     '#attached'=> array(
-      'js' => array(
-        $module_path . '/toolbar.js',
+      'library' => array(
+        array('toolbar', 'drupal.toolbar'),
       ),
-      'css' => array(
-        $module_path . '/toolbar.css',
-      ),
-      'library' => array(array('system', 'jquery.cookie')),
     ),
   );
 
@@ -362,3 +357,28 @@ function toolbar_in_active_trail($path) {
   }
   return in_array($path, $active_paths);
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function toolbar_library_info() {
+  $libraries['drupal.toolbar'] = array(
+    'title' => 'Toolbar',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'toolbar') . '/toolbar.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'toolbar') . '/toolbar.css',
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+      array('system', 'jquery.once'),
+      array('system', 'jquery.cookie'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index 909117f12408a6622f100570ec52181bc1ab648f..ce4163fd7f71c3ffeb8fc7cc8f4daa8f4ebfe39f 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -116,9 +116,7 @@ function translation_permission() {
 function translation_form_node_type_form_alter(&$form, &$form_state) {
   // Hide form element if default language is a constant.
   // TODO: When form #states allows OR values change this to use form #states.
-  $form['#attached']['js'] = array(
-    drupal_get_path('module', 'translation') . '/translation.js',
-  );
+  $form['#attached']['library'][] = array('translation', 'drupal.translation');
   // Add translation option to content type form.
   $form['language']['node_type_language_translation_enabled'] = array(
     '#type' => 'checkbox',
@@ -540,3 +538,22 @@ function translation_language_switch_links_alter(array &$links, $type, $path) {
     }
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function translation_library_info() {
+  $libraries['drupal.translation'] = array(
+    'title' => 'Translation',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'translation') . '/translation.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+    ),
+  );
+
+  return $libraries;
+}
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index 2268ae11b0b1ccf7bf7ea62b5839475e4c1f3903..3c39f24bcabd73938109d937dbf2f0c9304c8c26 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -360,7 +360,7 @@ function user_admin_settings($form, &$form_state) {
     '#title' => t('Enable user pictures.'),
     '#default_value' => $picture_support,
   );
-  drupal_add_js(drupal_get_path('module', 'user') . '/user.js');
+  $form['#attached']['library'][] = array('user', 'drupal.user');
   $form['personalization']['pictures'] = array(
     '#type' => 'container',
     '#states' => array(
@@ -738,7 +738,7 @@ function user_admin_permissions($form, $form_state, $rid = NULL) {
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save permissions'));
 
-  $form['#attached']['js'][] = drupal_get_path('module', 'user') . '/user.permissions.js';
+  $form['#attached']['library'][] = array('user', 'drupal.user.permissions');
 
   return $form;
 }
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index e90c907eb57132bd4464206e39460a98ab2d2bf7..213a349c6af328eb93f984395c442290480aa35a 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -3081,7 +3081,7 @@ function user_form_process_password_confirm($element) {
     ),
   );
 
-  $element['#attached']['js'][] = drupal_get_path('module', 'user') . '/user.js';
+  $element['#attached']['library'][] = array('user', 'drupal.user');
   // Ensure settings are only added once per page.
   static $already_added = FALSE;
   if (!$already_added) {
@@ -3198,7 +3198,7 @@ function user_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id
       // a custom behavior, since the #states system would also synchronize on
       // uncheck.
       '#attached' => array(
-        'js' => array(drupal_get_path('module', 'user') . '/user.js'),
+        'library' => array(array('user', 'drupal.user')),
       ),
     );
 
@@ -3314,3 +3314,36 @@ function user_file_download_access($field, EntityInterface $entity, File $file)
     return user_view_access($entity);
   }
 }
+
+/**
+ * Implements hook_library_info().
+ */
+function user_library_info() {
+  $libraries['drupal.user'] = array(
+    'title' => 'User',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'user') . '/user.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'jquery.once'),
+    ),
+  );
+
+  $libraries['drupal.user.permissions'] = array(
+    'title' => 'User permissions',
+    'version' => VERSION,
+    'js' => array(
+      drupal_get_path('module', 'user') . '/user.permissions.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'jquery'),
+      array('system', 'drupal'),
+      array('system', 'drupal.settings'),
+    ),
+  );
+
+  return $libraries;
+}