Skip to content
This repository was archived by the owner on Jul 30, 2026. It is now read-only.

Repository files navigation

WebExtension browser API Polyfill

This library allows extensions to use the Promise-based browser API namespace to access WebExtension APIs. Firefox pioneered this API as an alternative to the callback-based chrome namespace from Chrome, and offered this polyfill to enable Chrome extensions to use the same API. Safari also supports the browser namespace.

Chrome 148 added support for the browser namespace for all extensions except devtools extensions. This exception was lifted in Chrome 152, which supports the browser namespace for all Chrome extensions.

For more information on Chrome's new support for the browser namespace, see https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace

Following the adoption of the browser namespace by Chrome, this polyfill has served its purpose, and will not receive any further updates.

Table of contents

Supported Browsers

Browser Support Level
Chrome Officially Supported (with automated tests)
Firefox Officially Supported as a NO-OP (with automated tests for comparison with the behaviors on Chrome)
Opera / Edge (>=79.0.309) Unofficially Supported as a Chrome-compatible target (but not explicitly tested in automation)
Safari Unofficially Supported as a NO-OP (but not explicitly tested in automation)

The polyfill is being tested explicitly (with automated tests that run on every pull request) on officially supported browsers (that are currently the last stable versions of Chrome and Firefox).

On Firefox, this library is actually acting as a NO-OP: it detects that the browser API object is already defined and it does not create any custom wrappers. Firefox is still included in the automated tests, to ensure that no wrappers are being created when running on Firefox, and for comparison with the behaviors implemented by the library on Chrome.

On browsers supporting the browser namespace, this library acts as a NO-OP. See the top of this file - in 2027 this library is likely redundant.

Installation

A new version of the library is built from this repository and released as an npm package.

The npm package is named after this repo: webextension-polyfill.

For the extension that already include a package.json file, the last released version of this library can be quickly installed using:

npm install --save-dev webextension-polyfill

Inside the dist/ directory of the npm package, there are both the minified and non-minified builds (and their related source map files):

  • node_modules/webextension-polyfill/dist/browser-polyfill.js
  • node_modules/webextension-polyfill/dist/browser-polyfill.min.js

For extensions that do not include a package.json file and/or prefer to download and add the library directly into their own code repository, all the versions released on npm are also available for direct download from unpkg.com:

and linked to the Github releases:

Basic Setup

In order to use the polyfill, it must be loaded into any context where browser APIs are accessed. The most common cases are background and content scripts, which can be specified in manifest.json (make sure to include the browser-polyfill.js script before any other scripts that use it):

{
  // ...

  "background": {
    "scripts": [
      "browser-polyfill.js",
      "background.js"
    ]
  },

  "content_scripts": [{
    // ...
    "js": [
      "browser-polyfill.js",
      "content.js"
    ]
  }]
}

For HTML documents, such as browserAction popups, or tab pages, it must be included more explicitly:

<!DOCTYPE html>
<html>
  <head>
    <script type="application/javascript" src="browser-polyfill.js"></script>
    <script type="application/javascript" src="popup.js"></script>
  </head>
  <!-- ... -->
</html>

And for dynamically-injected content scripts loaded by tabs.executeScript, it must be injected by a separate executeScript call, unless it has already been loaded via a content_scripts declaration in manifest.json:

browser.tabs.executeScript({file: "browser-polyfill.js"});
browser.tabs.executeScript({file: "content.js"}).then(result