diff --git a/BUILD b/BUILD
index 8b11bd5..7e2c5c6 100644
--- a/BUILD
+++ b/BUILD
@@ -15,11 +15,14 @@
 
 genrule2(
     name = "cm-static",
-    srcs = [":codemirror_editor"],
+    srcs = [
+        ":codemirror-element",
+        ":codemirror_editor",
+    ],
     outs = ["cm-static.jar"],
     cmd = " && ".join([
         "mkdir $$TMP/static",
-        "cp -r $(locations :codemirror_editor) $$TMP/static",
+        "cp $(SRCS) $$TMP/static",
         "cd $$TMP",
         "zip -Drq $$ROOT/$@ -g .",
     ]),
@@ -40,7 +43,4 @@
 polygerrit_plugin(
     name = "codemirror_editor",
     app = "gr-editor/gr-editor.js",
-    assets = [
-        ":codemirror-element",
-    ],
 )
diff --git a/README.md b/README.md
index c85c098..96d3063 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
 
 You will need `polymer-bridges` which is a submodule you can clone from: https://gerrit-review.googlesource.com/admin/repos/polymer-bridges
 
-As polymer 3 no longer support `Polymer.importHref` anymore, Gerrit still supports through a custom implementation, the implementation is copied here for testing purpose (`test/import-href.js`).
+As polymer 3 no longer support `Polymer.importHref` anymore, this plugin still supports it through a custom implementation in `gr-editor.js`.
 
 ## Test plugin on Gerrit
 
@@ -28,4 +28,4 @@
 
 If your plugin is already enabled, then you can block it and then inject the compiled local verison.
 
-See more about how to use dev helper extension to help you test here: https://gerrit.googlesource.com/gerrit-fe-dev-helper/+/master
\ No newline at end of file
+See more about how to use dev helper extension to help you test here: https://gerrit.googlesource.com/gerrit-fe-dev-helper/+/master
diff --git a/bower.json b/bower.json
index 6de966f..f932829 100644
--- a/bower.json
+++ b/bower.json
@@ -5,7 +5,7 @@
   ],
   "license": "http://www.apache.org/licenses/LICENSE-2.0",
   "dependencies": {
-    "codemirror-minified": "^5.50.2"
+    "codemirror-minified": "^5.59.1"
   },
   "devDependencies": {
     "es6-promise": "^3.3.1",
diff --git a/gr-editor/gr-editor.js b/gr-editor/gr-editor.js
index d7297ad..c88e2a8 100644
--- a/gr-editor/gr-editor.js
+++ b/gr-editor/gr-editor.js
@@ -15,6 +15,86 @@
  * limitations under the License.
  */
 
+// Run a callback when HTMLImports are ready or immediately if
+// this api is not available.
+function whenImportsReady(cb) {
+  if (window.HTMLImports) {
+    HTMLImports.whenReady(cb);
+  } else {
+    cb();
+  }
+}
+
+/**
+ * Convenience method for importing an HTML document imperatively. Mostly copied
+ * from polymer/lib/utils/import-href.html.
+ *
+ * This method creates a new `<link rel="import">` element with
+ * the provided URL and appends it to the document to start loading.
+ * In the `onload` callback, the `import` property of the `link`
+ * element will contain the imported document contents.
+ *
+ * @param {string} href URL to document to load.
+ * @param {?function(!Event):void=} onload Callback to notify when an import successfully
+ *   loaded.
+ * @param {?function(!ErrorEvent):void=} onerror Callback to notify when an import
+ *   unsuccessfully loaded.
+ */
+function importHref(href, onload, onerror) {
+  let link =
+      /** @type {HTMLLinkElement} */
+      (document.head.querySelector('link[href="' + href + '"][import-href]'));
+  if (!link) {
+    link = /** @type {HTMLLinkElement} */ (document.createElement('link'));
+    link.setAttribute('rel', 'import');
+    link.setAttribute('href', href);
+    link.setAttribute('import-href', '');
+  }
+  // NOTE: the link may now be in 3 states: (1) pending insertion,
+  // (2) inflight, (3) already loaded. In each case, we need to add
+  // event listeners to process callbacks.
+  const cleanup = function() {
+    link.removeEventListener('load', loadListener);
+    link.removeEventListener('error', errorListener);
+  };
+  const loadListener = function(event) {
+    cleanup();
+    // In case of a successful load, cache the load event on the link so
+    // that it can be used to short-circuit this method in the future when
+    // it is called with the same href param.
+    link.__dynamicImportLoaded = true;
+    if (onload) {
+      whenImportsReady(() => {
+        onload(event);
+      });
+    }
+  };
+  const errorListener = function(event) {
+    cleanup();
+    // In case of an error, remove the link from the document so that it
+    // will be automatically created again the next time `importHref` is
+    // called.
+    if (link.parentNode) {
+      link.parentNode.removeChild(link);
+    }
+    if (onerror) {
+      whenImportsReady(() => {
+        onerror(event);
+      });
+    }
+  };
+  link.addEventListener('load', loadListener);
+  link.addEventListener('error', errorListener);
+  if (link.parentNode == null) {
+    document.head.appendChild(link);
+    // if the link already loaded, dispatch a fake load event
+    // so that listeners are called and get a proper event argument.
+  } else if (link.__dynamicImportLoaded) {
+    link.dispatchEvent(new Event('load'));
+  }
+  return link;
+}
+
 // we need to be on codemirror 5.33.0+ to get the support for
 // text/x-php in CodeMirror.findModeByMIME
 const LANGUAGE_MAP = {
@@ -87,7 +167,7 @@
     const codemirrorElementFile = '/static/codemirror-element.html';
     const url = this.plugin.url(codemirrorElementFile);
     return new Promise((resolve, reject) => {
-      Polymer.importHref(url, resolve, reject);
+      importHref(url, resolve, reject);
     });
   }
 
@@ -159,9 +239,8 @@
 
 customElements.define(GrEditor.is, GrEditor);
 
-// Install the plugin
 if (window.Gerrit) {
   Gerrit.install(plugin => {
     plugin.registerCustomComponent('editor', 'gr-editor', {replace: true});
   });
-}
\ No newline at end of file
+}
diff --git a/gr-editor/gr-editor_test.html b/gr-editor/gr-editor_test.html
index 586d703..fcbcb5f 100644
--- a/gr-editor/gr-editor_test.html
+++ b/gr-editor/gr-editor_test.html
@@ -31,6 +31,7 @@
 <script type="module">
 import '../test/common-test-setup.js';
 import './gr-editor.js';
+import {importHref} from './gr-editor.js';
 suite('gr-editor tests', () => {
   let element;
   let sandbox;
@@ -41,7 +42,7 @@
     stub('gr-editor', {
       _importCodeMirror() {
         return new Promise((resolve, reject) => {
-          Polymer.importHref('./codemirror-element.html', resolve, reject);
+          importHref('./codemirror-element.html', resolve, reject);
         });
       },
     });
diff --git a/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java b/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java
index 0bba486..c1ccee3 100644
--- a/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java
+++ b/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java
@@ -23,6 +23,6 @@
   @Override
   protected void configure() {
     DynamicSet.bind(binder(), WebUiPlugin.class)
-        .toInstance(new JavaScriptPlugin("codemirror_editor.html"));
+        .toInstance(new JavaScriptPlugin("codemirror_editor.js"));
   }
 }
diff --git a/test/common-test-setup.js b/test/common-test-setup.js
index a0f1f1b..1158af4 100644
--- a/test/common-test-setup.js
+++ b/test/common-test-setup.js
@@ -57,6 +57,3 @@
 import 'polymer-bridges/polymer/polymer-legacy_bridge.js';
 
 import '@polymer/iron-test-helpers/iron-test-helpers.js';
-import {importHref} from './import-href.js';
-
-window.Polymer.importHref = importHref;
diff --git a/test/import-href.js b/test/import-href.js
deleted file mode 100644
index 80ae389..0000000
--- a/test/import-href.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// This file is a replacement for the
-// polymer-bridges/polymer/lib/utils/import-href.html file. The html
-// file contains code inside <script>...</script> and can't be imported
-// in es6 modules.
-
-// run a callback when HTMLImports are ready or immediately if
-// this api is not available.
-function whenImportsReady(cb) {
-  if (window.HTMLImports) {
-    HTMLImports.whenReady(cb);
-  } else {
-    cb();
-  }
-}
-
-/**
- * Convenience method for importing an HTML document imperatively.
- *
- * This method creates a new `<link rel="import">` element with
- * the provided URL and appends it to the document to start loading.
- * In the `onload` callback, the `import` property of the `link`
- * element will contain the imported document contents.
- *
- * @memberof Polymer
- * @param {string} href URL to document to load.
- * @param {?function(!Event):void=} onload Callback to notify when an import successfully
- *   loaded.
- * @param {?function(!ErrorEvent):void=} onerror Callback to notify when an import
- *   unsuccessfully loaded.
- * @param {boolean=} optAsync True if the import should be loaded `async`.
- *   Defaults to `false`.
- * @return {!HTMLLinkElement} The link element for the URL to be loaded.
- */
-export function importHref(href, onload, onerror, optAsync) {
-  let link =
-    /** @type {HTMLLinkElement} */
-    (document.head.querySelector('link[href="' + href + '"][import-href]'));
-  if (!link) {
-    link = /** @type {HTMLLinkElement} */ (document.createElement("link"));
-    link.rel = "import";
-    link.href = href;
-    link.setAttribute("import-href", "");
-  }
-  // always ensure link has `async` attribute if user specified one,
-  // even if it was previously not async. This is considered less confusing.
-  if (optAsync) {
-    link.setAttribute("async", "");
-  }
-  // NOTE: the link may now be in 3 states: (1) pending insertion,
-  // (2) inflight, (3) already loaded. In each case, we need to add
-  // event listeners to process callbacks.
-  const cleanup = function () {
-    link.removeEventListener("load", loadListener);
-    link.removeEventListener("error", errorListener);
-  };
-  const loadListener = function (event) {
-    cleanup();
-    // In case of a successful load, cache the load event on the link so
-    // that it can be used to short-circuit this method in the future when
-    // it is called with the same href param.
-    link.__dynamicImportLoaded = true;
-    if (onload) {
-      whenImportsReady(() => {
-        onload(event);
-      });
-    }
-  };
-  const errorListener = function (event) {
-    cleanup();
-    // In case of an error, remove the link from the document so that it
-    // will be automatically created again the next time `importHref` is
-    // called.
-    if (link.parentNode) {
-      link.parentNode.removeChild(link);
-    }
-    if (onerror) {
-      whenImportsReady(() => {
-        onerror(event);
-      });
-    }
-  };
-  link.addEventListener("load", loadListener);
-  link.addEventListener("error", errorListener);
-  if (link.parentNode == null) {
-    document.head.appendChild(link);
-    // if the link already loaded, dispatch a fake load event
-    // so that listeners are called and get a proper event argument.
-  } else if (link.__dynamicImportLoaded) {
-    link.dispatchEvent(new Event("load"));
-  }
-  return link;
-}
