diff --git a/app/assets/javascripts/behaviors/quick_submit.js b/app/assets/javascripts/behaviors/quick_submit.js
index a7e68ae5cb96fc1f3047b770ae9e57a43f9d3992..626f3503c915bbe6f90b32d9fdaaffa490c81ed1 100644
--- a/app/assets/javascripts/behaviors/quick_submit.js
+++ b/app/assets/javascripts/behaviors/quick_submit.js
@@ -6,7 +6,7 @@
 // "Meta+Enter" (Mac) or "Ctrl+Enter" (Linux/Windows) key combination, the form
 // is submitted.
 //
-require('../extensions/jquery');
+import '../commons/bootstrap';
 
 //
 // ### Example Markup
diff --git a/app/assets/javascripts/behaviors/requires_input.js b/app/assets/javascripts/behaviors/requires_input.js
index 6b21695d082f40ee577f8f144ba381321e0b0ee5..eb7143f5b1a2d9860f5f324df9b86f35c9514cd1 100644
--- a/app/assets/javascripts/behaviors/requires_input.js
+++ b/app/assets/javascripts/behaviors/requires_input.js
@@ -4,7 +4,7 @@
 // When called on a form with input fields with the `required` attribute, the
 // form's submit button will be disabled until all required fields have values.
 //
-require('../extensions/jquery');
+import '../commons/bootstrap';
 
 //
 // ### Example Markup
diff --git a/app/assets/javascripts/commons/bootstrap.js b/app/assets/javascripts/commons/bootstrap.js
index db0cbfd87c33b9dcb39187b817409cd353993c56..36bfe457be90762dac1a81e0a21840b91d98d248 100644
--- a/app/assets/javascripts/commons/bootstrap.js
+++ b/app/assets/javascripts/commons/bootstrap.js
@@ -1,4 +1,4 @@
-import 'jquery';
+import $ from 'jquery';
 
 // bootstrap jQuery plugins
 import 'bootstrap-sass/assets/javascripts/bootstrap/affix';
@@ -8,3 +8,9 @@ import 'bootstrap-sass/assets/javascripts/bootstrap/modal';
 import 'bootstrap-sass/assets/javascripts/bootstrap/tab';
 import 'bootstrap-sass/assets/javascripts/bootstrap/transition';
 import 'bootstrap-sass/assets/javascripts/bootstrap/tooltip';
+
+// custom jQuery functions
+$.fn.extend({
+  disable() { return $(this).attr('disabled', 'disabled').addClass('disabled'); },
+  enable() { return $(this).removeAttr('disabled').removeClass('disabled'); },
+});
diff --git a/app/assets/javascripts/commons/index.js b/app/assets/javascripts/commons/index.js
index 72ede1d621ad3c88412b31c912937698abb769a0..7063f59d446abcdc52630c66aad3526905c3d678 100644
--- a/app/assets/javascripts/commons/index.js
+++ b/app/assets/javascripts/commons/index.js
@@ -1,2 +1,3 @@
+import './polyfills';
 import './jquery';
 import './bootstrap';
diff --git a/app/assets/javascripts/commons/polyfills.js b/app/assets/javascripts/commons/polyfills.js
new file mode 100644
index 0000000000000000000000000000000000000000..fbd0db64ca7a8bc9e8471417f87ea3ac967d61d9
--- /dev/null
+++ b/app/assets/javascripts/commons/polyfills.js
@@ -0,0 +1,10 @@
+// ECMAScript polyfills
+import 'core-js/fn/array/find';
+import 'core-js/fn/object/assign';
+import 'core-js/fn/promise';
+import 'core-js/fn/string/code-point-at';
+import 'core-js/fn/string/from-code-point';
+
+// Browser polyfills
+import './polyfills/custom_event';
+import './polyfills/element';
diff --git a/app/assets/javascripts/commons/polyfills/custom_event.js b/app/assets/javascripts/commons/polyfills/custom_event.js
new file mode 100644
index 0000000000000000000000000000000000000000..aea61b82d03b3105b7970c97ca630000e07cfeb7
--- /dev/null
+++ b/app/assets/javascripts/commons/polyfills/custom_event.js
@@ -0,0 +1,9 @@
+if (typeof window.CustomEvent !== 'function') {
+  window.CustomEvent = function CustomEvent(event, params) {
+    const evt = document.createEvent('CustomEvent');
+    const evtParams = params || { bubbles: false, cancelable: false, detail: undefined };
+    evt.initCustomEvent(event, evtParams.bubbles, evtParams.cancelable, evtParams.detail);
+    return evt;
+  };
+  window.CustomEvent.prototype = Event;
+}
diff --git a/app/assets/javascripts/commons/polyfills/element.js b/app/assets/javascripts/commons/polyfills/element.js
new file mode 100644
index 0000000000000000000000000000000000000000..9a1f73bf2ac432928907c8eee3e54760fe70cbe8
--- /dev/null
+++ b/app/assets/javascripts/commons/polyfills/element.js
@@ -0,0 +1,20 @@
+Element.prototype.closest = Element.prototype.closest ||
+  function closest(selector, selectedElement = this) {
+    if (!selectedElement) return null;
+    return selectedElement.matches(selector) ?
+      selectedElement :
+      Element.prototype.closest(selector, selectedElement.parentElement);
+  };
+
+Element.prototype.matches = Element.prototype.matches ||
+  Element.prototype.matchesSelector ||
+  Element.prototype.mozMatchesSelector ||
+  Element.prototype.msMatchesSelector ||
+  Element.prototype.oMatchesSelector ||
+  Element.prototype.webkitMatchesSelector ||
+  function matches(selector) {
+    const elms = (this.document || this.ownerDocument).querySelectorAll(selector);
+    let i = elms.length - 1;
+    while (i >= 0 && elms.item(i) !== this) { i -= 1; }
+    return i > -1;
+  };
diff --git a/app/assets/javascripts/droplab/droplab_ajax.js b/app/assets/javascripts/droplab/droplab_ajax.js
index f61be741b4ae8aa9d2858b35018570b23c62ae2a..020f8b4ac6567fe2af64d86c1e4d37a6575cee8b 100644
--- a/app/assets/javascripts/droplab/droplab_ajax.js
+++ b/app/assets/javascripts/droplab/droplab_ajax.js
@@ -74,6 +74,9 @@ require('../window')(function(w){
         this._loadUrlData(config.endpoint)
           .then(function(d) {
             self._loadData(d, config, self);
+          }, function(xhrError) {
+            // TODO: properly handle errors due to XHR cancellation
+            return;
           }).catch(function(e) {
             throw new droplabAjaxException(e.message || e);
           });
diff --git a/app/assets/javascripts/droplab/droplab_ajax_filter.js b/app/assets/javascripts/droplab/droplab_ajax_filter.js
index b63d73066cb6717383bdc4ef08b81678fdd87ba1..05eba7aef56064dd0ab0887c16876d9441bed0d2 100644
--- a/app/assets/javascripts/droplab/droplab_ajax_filter.js
+++ b/app/assets/javascripts/droplab/droplab_ajax_filter.js
@@ -82,6 +82,9 @@ require('../window')(function(w){
         this._loadUrlData(url)
           .then(function(data) {
             self._loadData(data, config, self);
+          }, function(xhrError) {
+            // TODO: properly handle errors due to XHR cancellation
+            return;
           });
       }
     },
diff --git a/app/assets/javascripts/extensions/array.js b/app/assets/javascripts/extensions/array.js
index f8256a8d26d42549273d9d481f40a5e1ad2bb7e8..027222f804dfc023f8a38a482b33031d81ee2cb4 100644
--- a/app/assets/javascripts/extensions/array.js
+++ b/app/assets/javascripts/extensions/array.js
@@ -1,27 +1,11 @@
-/* eslint-disable no-extend-native, func-names, space-before-function-paren, space-infix-ops, strict, max-len */
+// TODO: remove this
 
-'use strict';
-
-Array.prototype.first = function() {
+// eslint-disable-next-line no-extend-native
+Array.prototype.first = function first() {
   return this[0];
 };
 
-Array.prototype.last = function() {
-  return this[this.length-1];
-};
-
-Array.prototype.find = Array.prototype.find || function(predicate, ...args) {
-  if (!this) throw new TypeError('Array.prototype.find called on null or undefined');
-  if (typeof predicate !== 'function') throw new TypeError('predicate must be a function');
-
-  const list = Object(this);
-  const thisArg = args[1];
-  let value = {};
-
-  for (let i = 0; i < list.length; i += 1) {
-    value = list[i];
-    if (predicate.call(thisArg, value, i, list)) return value;
-  }
-
-  return undefined;
+// eslint-disable-next-line no-extend-native
+Array.prototype.last = function last() {
+  return this[this.length - 1];
 };
diff --git a/app/assets/javascripts/extensions/custom_event.js b/app/assets/javascripts/extensions/custom_event.js
deleted file mode 100644
index abedae4c1c7a669fad71f73180153be3f09dcde8..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/extensions/custom_event.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* global CustomEvent */
-/* eslint-disable no-global-assign */
-
-// Custom event support for IE
-CustomEvent = function CustomEvent(event, parameters) {
-  const params = parameters || { bubbles: false, cancelable: false, detail: undefined };
-  const evt = document.createEvent('CustomEvent');
-  evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
-  return evt;
-};
-
-CustomEvent.prototype = window.Event.prototype;
diff --git a/app/assets/javascripts/extensions/element.js b/app/assets/javascripts/extensions/element.js
deleted file mode 100644
index 90ab79305a7584a7c7c67c9b32510634b3155ab6..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/extensions/element.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* global Element */
-/* eslint-disable consistent-return, max-len, no-empty, func-names */
-
-Element.prototype.closest = Element.prototype.closest || function closest(selector, selectedElement = this) {
-  if (!selectedElement) return;
-  return selectedElement.matches(selector) ? selectedElement : Element.prototype.closest(selector, selectedElement.parentElement);
-};
-
-Element.prototype.matches = Element.prototype.matches ||
-  Element.prototype.matchesSelector ||
-  Element.prototype.mozMatchesSelector ||
-  Element.prototype.msMatchesSelector ||
-  Element.prototype.oMatchesSelector ||
-  Element.prototype.webkitMatchesSelector ||
-  function (s) {
-    const matches = (this.document || this.ownerDocument).querySelectorAll(s);
-    let i = matches.length - 1;
-    while (i >= 0 && matches.item(i) !== this) { i -= 1; }
-    return i > -1;
-  };
diff --git a/app/assets/javascripts/extensions/jquery.js b/app/assets/javascripts/extensions/jquery.js
deleted file mode 100644
index 1a489b859e80b25dcb56eed4eb4fb1ef0b574047..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/extensions/jquery.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* eslint-disable func-names, space-before-function-paren, object-shorthand, comma-dangle, max-len */
-// Disable an element and add the 'disabled' Bootstrap class
-(function() {
-  $.fn.extend({
-    disable: function() {
-      return $(this).attr('disabled', 'disabled').addClass('disabled');
-    }
-  });
-
-  // Enable an element and remove the 'disabled' Bootstrap class
-  $.fn.extend({
-    enable: function() {
-      return $(this).removeAttr('disabled').removeClass('disabled');
-    }
-  });
-}).call(window);
diff --git a/app/assets/javascripts/extensions/object.js b/app/assets/javascripts/extensions/object.js
deleted file mode 100644
index 70a2d765abd04cfdb9e140a1db86dda483c24e4d..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/extensions/object.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* eslint-disable no-restricted-syntax */
-
-// Adapted from https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill
-if (typeof Object.assign !== 'function') {
-  Object.assign = function assign(target, ...args) {
-    if (target == null) { // TypeError if undefined or null
-      throw new TypeError('Cannot convert undefined or null to object');
-    }
-
-    const to = Object(target);
-
-    for (let index = 0; index < args.length; index += 1) {
-      const nextSource = args[index];
-
-      if (nextSource != null) { // Skip over if undefined or null
-        for (const nextKey in nextSource) {
-          // Avoid bugs when hasOwnProperty is shadowed
-          if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
-            to[nextKey] = nextSource[nextKey];
-          }
-        }
-      }
-    }
-    return to;
-  };
-}
diff --git a/app/assets/javascripts/extensions/string.js b/app/assets/javascripts/extensions/string.js
deleted file mode 100644
index ae9662444b0b8144d120b691c3c6f607e23d2bf8..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/extensions/string.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import 'string.prototype.codepointat';
-import 'string.fromcodepoint';
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
index e1a9707043973ffefb99be08db8c64d9b68778d5..d37c812c1f781091deb121d36a16a684c4ee4c4e 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
@@ -162,6 +162,10 @@
     }
 
     resetDropdowns() {
+      if (!this.currentDropdown) {
+        return;
+      }
+
       // Force current dropdown to hide
       this.mapping[this.currentDropdown].reference.hideDropdown();
 
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index 638fe744668cd3a51157b16c9ba80c82de75e172..835e87a28d78c698b2dcdde924aae900c7376c51 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
@@ -38,7 +38,8 @@
       this.editTokenWrapper = this.editToken.bind(this);
       this.tokenChange = this.tokenChange.bind(this);
 
-      this.filteredSearchInput.form.addEventListener('submit', this.handleFormSubmit);
+      this.filteredSearchInputForm = this.filteredSearchInput.form;
+      this.filteredSearchInputForm.addEventListener('submit', this.handleFormSubmit);
       this.filteredSearchInput.addEventListener('input', this.setDropdownWrapper);
       this.filteredSearchInput.addEventListener('input', this.toggleClearSearchButtonWrapper);
       this.filteredSearchInput.addEventListener('input', this.handleInputPlaceholderWrapper);
@@ -56,7 +57,7 @@
     }
 
     unbindEvents() {
-      this.filteredSearchInput.form.removeEventListener('submit', this.handleFormSubmit);
+      this.filteredSearchInputForm.removeEventListener('submit', this.handleFormSubmit);
       this.filteredSearchInput.removeEventListener('input', this.setDropdownWrapper);
       this.filteredSearchInput.removeEventListener('input', this.toggleClearSearchButtonWrapper);
       this.filteredSearchInput.removeEventListener('input', this.handleInputPlaceholderWrapper);
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 604ed91627ab3ca8e8d5d5ae90f1dae1a32fa696..cf3e4ee77b63b2d1f348ecd33d51bec2b5d0f2ce 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -16,17 +16,9 @@ import Sortable from 'vendor/Sortable';
 import 'mousetrap';
 import 'mousetrap/plugins/pause/mousetrap-pause';
 import 'vendor/fuzzaldrin-plus';
-import promisePolyfill from 'es6-promise';
 
 // extensions
-import './extensions/string';
 import './extensions/array';
-import './extensions/custom_event';
-import './extensions/element';
-import './extensions/jquery';
-import './extensions/object';
-
-promisePolyfill.polyfill();
 
 // expose common libraries as globals (TODO: remove these)
 window.jQuery = jQuery;
diff --git a/app/assets/javascripts/monitoring/prometheus_graph.js b/app/assets/javascripts/monitoring/prometheus_graph.js
index 9384fe3f276a0d06188dd1b17db9e025fefb88b3..71eb746edac26b9c9dbef0cc2eefd8b2a9e1760d 100644
--- a/app/assets/javascripts/monitoring/prometheus_graph.js
+++ b/app/assets/javascripts/monitoring/prometheus_graph.js
@@ -1,9 +1,11 @@
-/* eslint-disable no-new*/
+/* eslint-disable no-new */
+/* global Flash */
+
 import d3 from 'd3';
 import _ from 'underscore';
 import statusCodes from '~/lib/utils/http_status';
 import '~/lib/utils/common_utils';
-import Flash from '~/flash';
+import '~/flash';
 
 const prometheusGraphsContainer = '.prometheus-graph';
 const metricsEndpoint = 'metrics.json';
diff --git a/changelogs/unreleased/use-corejs-polyfills.yml b/changelogs/unreleased/use-corejs-polyfills.yml
new file mode 100644
index 0000000000000000000000000000000000000000..381f80c5c0d3d0d46d632aa12214216167dd54e3
--- /dev/null
+++ b/changelogs/unreleased/use-corejs-polyfills.yml
@@ -0,0 +1,4 @@
+---
+title: Standardize on core-js for es2015 polyfills
+merge_request: 9749
+author:
diff --git a/package.json b/package.json
index efa3a63e693d4e6ddab4d7a6489e6c904be780f3..9652dd8f9720eaaa5666c569cf0a2f8d8ebcfade 100644
--- a/package.json
+++ b/package.json
@@ -17,11 +17,11 @@
     "babel-preset-stage-2": "^6.22.0",
     "bootstrap-sass": "^3.3.6",
     "compression-webpack-plugin": "^0.3.2",
+    "core-js": "^2.4.1",
     "d3": "^3.5.11",
     "document-register-element": "^1.3.0",
     "dropzone": "^4.2.0",
     "emoji-unicode-version": "^0.2.1",
-    "es6-promise": "^4.0.5",
     "jquery": "^2.2.1",
     "jquery-ujs": "^1.2.1",
     "js-cookie": "^2.1.3",
@@ -31,8 +31,6 @@
     "raw-loader": "^0.5.1",
     "select2": "3.5.2-browserify",
     "stats-webpack-plugin": "^0.4.3",
-    "string.fromcodepoint": "^0.2.1",
-    "string.prototype.codepointat": "^0.2.0",
     "timeago.js": "^2.0.5",
     "underscore": "^1.8.3",
     "vue": "^2.1.10",
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
index 9a2978006aaf4cfb7c257598c2431e6a5963047d..0a6e042b7009ed5fa14558de2d6e68433c19683d 100644
--- a/spec/javascripts/awards_handler_spec.js
+++ b/spec/javascripts/awards_handler_spec.js
@@ -1,11 +1,8 @@
 /* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, no-unused-expressions, comma-dangle, new-parens, no-unused-vars, quotes, jasmine/no-spec-dupes, prefer-template, max-len */
 
-import promisePolyfill from 'es6-promise';
 import Cookies from 'js-cookie';
 import AwardsHandler from '~/awards_handler';
 
-promisePolyfill.polyfill();
-
 (function() {
   var awardsHandler, lazyAssert, urlRoot, openAndWaitForEmojiMenu;
 
diff --git a/spec/javascripts/blob/create_branch_dropdown_spec.js b/spec/javascripts/blob/create_branch_dropdown_spec.js
index dafb43761e02cec0f1292bb638ac42681fac19ab..c1179e572ae44f6d738472b1abe968bfe83a15cd 100644
--- a/spec/javascripts/blob/create_branch_dropdown_spec.js
+++ b/spec/javascripts/blob/create_branch_dropdown_spec.js
@@ -1,5 +1,3 @@
-require('jquery');
-require('~/extensions/jquery.js');
 require('~/gl_dropdown');
 require('~/lib/utils/type_utility');
 require('~/blob/create_branch_dropdown');
diff --git a/spec/javascripts/blob/target_branch_dropdown_spec.js b/spec/javascripts/blob/target_branch_dropdown_spec.js
index 6f3eb4cc7eb6b147c85ec7503aa6252c907aaf4a..4fb79663c516516086f2aaf50b35925fe30f3114 100644
--- a/spec/javascripts/blob/target_branch_dropdown_spec.js
+++ b/spec/javascripts/blob/target_branch_dropdown_spec.js
@@ -1,5 +1,3 @@
-require('jquery');
-require('~/extensions/jquery.js');
 require('~/gl_dropdown');
 require('~/lib/utils/type_utility');
 require('~/blob/create_branch_dropdown');
diff --git a/spec/javascripts/boards/board_new_issue_spec.js b/spec/javascripts/boards/board_new_issue_spec.js
index 22c9f12951b84b73ceb64d03e12ec3fa26f01986..4999933c0c175f0ce71cfd5b2674b62f6453e7ce 100644
--- a/spec/javascripts/boards/board_new_issue_spec.js
+++ b/spec/javascripts/boards/board_new_issue_spec.js
@@ -8,7 +8,6 @@ import boardNewIssue from '~/boards/components/board_new_issue';
 
 require('~/boards/models/list');
 require('./mock_data');
-require('es6-promise').polyfill();
 
 describe('Issue boards new issue form', () => {
   let vm;
diff --git a/spec/javascripts/boards/boards_store_spec.js b/spec/javascripts/boards/boards_store_spec.js
index 49a2ca4a78fff221f7774b6aa7eef68da049c0f4..1d1069600fc636ec94896515fd10bd97b810a518 100644
--- a/spec/javascripts/boards/boards_store_spec.js
+++ b/spec/javascripts/boards/boards_store_spec.js
@@ -15,7 +15,6 @@ require('~/boards/models/user');
 require('~/boards/services/board_service');
 require('~/boards/stores/boards_store');
 require('./mock_data');
-require('es6-promise').polyfill();
 
 describe('Store', () => {
   beforeEach(() => {
diff --git a/spec/javascripts/extensions/jquery_spec.js b/spec/javascripts/bootstrap_jquery_spec.js
similarity index 93%
rename from spec/javascripts/extensions/jquery_spec.js
rename to spec/javascripts/bootstrap_jquery_spec.js
index 096d3272eac164a1ac87f6906b4bce438832a060..48994b7c523308c2b379fe581c7926d952a47ce5 100644
--- a/spec/javascripts/extensions/jquery_spec.js
+++ b/spec/javascripts/bootstrap_jquery_spec.js
@@ -1,9 +1,9 @@
 /* eslint-disable space-before-function-paren, no-var */
 
-require('~/extensions/jquery');
+import '~/commons/bootstrap';
 
 (function() {
-  describe('jQuery extensions', function() {
+  describe('Bootstrap jQuery extensions', function() {
     describe('disable', function() {
       beforeEach(function() {
         return setFixtures('<input type="text" />');
diff --git a/spec/javascripts/extensions/array_spec.js b/spec/javascripts/extensions/array_spec.js
index 60f6b9b78e3b77f9fd09feefaf991b3cf13891a2..4b871fe967d536d8a1ffe9ef20cac427b291b4fa 100644
--- a/spec/javascripts/extensions/array_spec.js
+++ b/spec/javascripts/extensions/array_spec.js
@@ -18,28 +18,5 @@ require('~/extensions/array');
         return expect(arr.last()).toBe(5);
       });
     });
-
-    describe('find', function () {
-      beforeEach(() => {
-        this.arr = [0, 1, 2, 3, 4, 5];
-      });
-
-      it('returns the item that first passes the predicate function', () => {
-        expect(this.arr.find(item => item === 2)).toBe(2);
-      });
-
-      it('returns undefined if no items pass the predicate function', () => {
-        expect(this.arr.find(item => item === 6)).not.toBeDefined();
-      });
-
-      it('error when called on undefined or null', () => {
-        expect(Array.prototype.find.bind(undefined, item => item === 1)).toThrow();
-        expect(Array.prototype.find.bind(null, item => item === 1)).toThrow();
-      });
-
-      it('error when predicate is not a function', () => {
-        expect(Array.prototype.find.bind(this.arr, 1)).toThrow();
-      });
-    });
   });
 }).call(window);
diff --git a/spec/javascripts/extensions/element_spec.js b/spec/javascripts/extensions/element_spec.js
deleted file mode 100644
index 2d8a128ed330964ad91645d8b60721411d4b5424..0000000000000000000000000000000000000000
--- a/spec/javascripts/extensions/element_spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-require('~/extensions/element');
-
-(() => {
-  describe('Element extensions', function () {
-    beforeEach(() => {
-      this.element = document.createElement('ul');
-    });
-
-    describe('matches', () => {
-      it('returns true if element matches the selector', () => {
-        expect(this.element.matches('ul')).toBeTruthy();
-      });
-
-      it("returns false if element doesn't match the selector", () => {
-        expect(this.element.matches('.not-an-element')).toBeFalsy();
-      });
-    });
-
-    describe('closest', () => {
-      beforeEach(() => {
-        this.childElement = document.createElement('li');
-        this.element.appendChild(this.childElement);
-      });
-
-      it('returns the closest parent that matches the selector', () => {
-        expect(this.childElement.closest('ul').toString()).toBe(this.element.toString());
-      });
-
-      it('returns itself if it matches the selector', () => {
-        expect(this.childElement.closest('li').toString()).toBe(this.childElement.toString());
-      });
-
-      it('returns undefined if nothing matches the selector', () => {
-        expect(this.childElement.closest('.no-an-element')).toBeFalsy();
-      });
-    });
-  });
-})();
diff --git a/spec/javascripts/extensions/object_spec.js b/spec/javascripts/extensions/object_spec.js
deleted file mode 100644
index 2467ed78459d090c3b502cc223c497576451f619..0000000000000000000000000000000000000000
--- a/spec/javascripts/extensions/object_spec.js
+++ /dev/null
@@ -1,25 +0,0 @@
-require('~/extensions/object');
-
-describe('Object extensions', () => {
-  describe('assign', () => {
-    it('merges source object into target object', () => {
-      const targetObj = {};
-      const sourceObj = {
-        foo: 'bar',
-      };
-      Object.assign(targetObj, sourceObj);
-      expect(targetObj.foo).toBe('bar');
-    });
-
-    it('merges object with the same properties', () => {
-      const targetObj = {
-        foo: 'bar',
-      };
-      const sourceObj = {
-        foo: 'baz',
-      };
-      Object.assign(targetObj, sourceObj);
-      expect(targetObj.foo).toBe('baz');
-    });
-  });
-});
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
index 81c1d81d181fe8c199425f66e399dfb48f1bce8d..ae9c263d1d75c54bc64c0c4ab0e99f905d249eb2 100644
--- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
@@ -41,7 +41,6 @@ const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper
         </div>
       `);
 
-      spyOn(gl.FilteredSearchManager.prototype, 'cleanup').and.callFake(() => {});
       spyOn(gl.FilteredSearchManager.prototype, 'loadSearchParamsFromURL').and.callFake(() => {});
       spyOn(gl.FilteredSearchManager.prototype, 'tokenChange').and.callFake(() => {});
       spyOn(gl.FilteredSearchDropdownManager.prototype, 'setDropdown').and.callFake(() => {});
@@ -54,6 +53,10 @@ const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper
       manager = new gl.FilteredSearchManager();
     });
 
+    afterEach(() => {
+      manager.cleanup();
+    });
+
     describe('search', () => {
       const defaultParams = '?scope=all&utf8=✓&state=opened';
 
diff --git a/spec/javascripts/gl_emoji_spec.js b/spec/javascripts/gl_emoji_spec.js
index 7ab0b37f2ec0769657da1b8a978f3ad2ddc37aff..9b44b25980ce0193ba2cea637bdc0e61d37a5998 100644
--- a/spec/javascripts/gl_emoji_spec.js
+++ b/spec/javascripts/gl_emoji_spec.js
@@ -1,6 +1,3 @@
-import '~/extensions/string';
-import '~/extensions/array';
-
 import { glEmojiTag } from '~/behaviors/gl_emoji';
 import {
   isEmojiUnicodeSupported,
diff --git a/spec/javascripts/monitoring/prometheus_graph_spec.js b/spec/javascripts/monitoring/prometheus_graph_spec.js
index 823b4bab7fc5cc3ff66bb4553782c80cdd78ba13..a3c1c5e1b7c1c7a1926567fa3d762d8fd4483eb7 100644
--- a/spec/javascripts/monitoring/prometheus_graph_spec.js
+++ b/spec/javascripts/monitoring/prometheus_graph_spec.js
@@ -1,11 +1,8 @@
 import 'jquery';
-import es6Promise from 'es6-promise';
 import '~/lib/utils/common_utils';
 import PrometheusGraph from '~/monitoring/prometheus_graph';
 import { prometheusMockData } from './prometheus_mock_data';
 
-es6Promise.polyfill();
-
 describe('PrometheusGraph', () => {
   const fixtureName = 'static/environments/metrics.html.raw';
   const prometheusGraphContainer = '.prometheus-graph';
diff --git a/spec/javascripts/polyfills/element_spec.js b/spec/javascripts/polyfills/element_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..ecaaf1907eaf5d898e243332ab3ece653c5f8354
--- /dev/null
+++ b/spec/javascripts/polyfills/element_spec.js
@@ -0,0 +1,36 @@
+import '~/commons/polyfills/element';
+
+describe('Element polyfills', function () {
+  beforeEach(() => {
+    this.element = document.createElement('ul');
+  });
+
+  describe('matches', () => {
+    it('returns true if element matches the selector', () => {
+      expect(this.element.matches('ul')).toBeTruthy();
+    });
+
+    it("returns false if element doesn't match the selector", () => {
+      expect(this.element.matches('.not-an-element')).toBeFalsy();
+    });
+  });
+
+  describe('closest', () => {
+    beforeEach(() => {
+      this.childElement = document.createElement('li');
+      this.element.appendChild(this.childElement);
+    });
+
+    it('returns the closest parent that matches the selector', () => {
+      expect(this.childElement.closest('ul').toString()).toBe(this.element.toString());
+    });
+
+    it('returns itself if it matches the selector', () => {
+      expect(this.childElement.closest('li').toString()).toBe(this.childElement.toString());
+    });
+
+    it('returns undefined if nothing matches the selector', () => {
+      expect(this.childElement.closest('.no-an-element')).toBeFalsy();
+    });
+  });
+});
diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js
index 4ac7e911740bc69ccf4e5ad32fb20999b722f2af..285b79401740a20b297bb8a3e8e50b0aca002c58 100644
--- a/spec/javascripts/right_sidebar_spec.js
+++ b/spec/javascripts/right_sidebar_spec.js
@@ -1,8 +1,8 @@
 /* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, new-parens, no-return-assign, new-cap, vars-on-top, max-len */
 /* global Sidebar */
 
-require('~/right_sidebar');
-require('~/extensions/jquery.js');
+import '~/commons/bootstrap';
+import '~/right_sidebar';
 
 (function() {
   var $aside, $icon, $labelsIcon, $page, $toggle, assertSidebarState;
diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/shortcuts_issuable_spec.js
index ffff643e37151d46e1097ef13a45c72c89a27abd..9e19dabd0e3e5efe1d31386f32c5b5a299d0514b 100644
--- a/spec/javascripts/shortcuts_issuable_spec.js
+++ b/spec/javascripts/shortcuts_issuable_spec.js
@@ -31,13 +31,9 @@ require('~/shortcuts_issuable');
           this.shortcut.replyWithSelectedText();
           expect($(this.selector).val()).toBe('');
         });
-        it('triggers `input`', function() {
-          var focused = false;
-          $(this.selector).on('focus', function() {
-            focused = true;
-          });
+        it('triggers `focus`', function() {
           this.shortcut.replyWithSelectedText();
-          expect(focused).toBe(true);
+          expect(document.activeElement).toBe(document.querySelector(this.selector));
         });
       });
       describe('with any selection', function() {
diff --git a/yarn.lock b/yarn.lock
index 55b8f1566ee00e14231b182522309a11c82d91b3..391b1c7eccfb211d953c27e24de607cd3b35ed70 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1213,7 +1213,7 @@ cookie@0.3.1:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
 
-core-js@^2.2.0, core-js@^2.4.0:
+core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1:
   version "2.4.1"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
 
@@ -1553,7 +1553,7 @@ es6-map@^0.1.3:
     es6-symbol "~3.1.0"
     event-emitter "~0.3.4"
 
-es6-promise@^4.0.5, es6-promise@~4.0.3:
+es6-promise@~4.0.3:
   version "4.0.5"
   resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.0.5.tgz#7882f30adde5b240ccfa7f7d78c548330951ae42"
 
@@ -4123,14 +4123,6 @@ string-width@^2.0.0:
     is-fullwidth-code-point "^2.0.0"
     strip-ansi "^3.0.0"
 
-string.fromcodepoint@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz#8d978333c0bc92538f50f383e4888f3e5619d653"
-
-string.prototype.codepointat@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz#6b26e9bd3afcaa7be3b4269b526de1b82000ac78"
-
 string_decoder@^0.10.25, string_decoder@~0.10.x:
   version "0.10.31"
   resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"