docs.rodeo

MDN Web Docs mirror

Chrome incompatibilities

{{AddonSidebar}} 

The WebExtension APIs aim to provide compatibility across all the main browsers, so extensions should run on any browser with minimal changes.

However, there are significant differences between Chrome (and Chromium-based browsers), Firefox, and Safari. In particular:

The rest of this page details these and other incompatibilities.

JavaScript APIs

chrome.* and browser.* namespace

Callbacks and promises

Firefox supports both the chrome and browser namespaces

As a porting aid, the Firefox implementation of WebExtensions supports chrome using callbacks and browser using promises. This means that many Chrome extensions work in Firefox without changes.

[!NOTE] The browser namespace is supported by Firefox and Safari. Chrome does not offer the browser namespace, until Chrome bug 798169 is resolved.

If you choose to write your extension to use browser and promises, Firefox provides a polyfill that should enable it to run in Chrome: https://github.com/mozilla/webextension-polyfill.

Partially supported APIs

The Browser support for JavaScript APIs page includes compatibility tables for all APIs that have any support in Firefox. Where there are caveats regarding support for an API method, property, type, or event, this is indicated in these tables with an asterisk “*”. Selecting the asterisk expands the table to display a note explaining the caveat.

The tables are generated from compatibility data stored as JSON files in GitHub.

The rest of this section describes the main compatibility issues you may need to consider when building a cross-browser extension. Also, remember to check the browser compatibility tables, as they may contain additional compatibility information.

Notifications API

For notifications.create(), with type "basic":

When the user clicks on a notification:

If you call notifications.create() more than once in rapid succession:

Proxy API

Firefox and Chrome include a Proxy API. However, the design of these two APIs is incompatible.

Firefox and Chrome provide incompatible APIs for working with a sidebar.

Tabs API

When using tabs.executeScript() or tabs.insertCSS():

To work cross-browser, you can specify the path as an absolute URL, starting at the extension’s root, like this:

/path/to/script.js

When calling tabs.remove():

WebRequest API

Windows API

Unsupported APIs

DeclarativeContent API

Miscellaneous incompatibilities

URLs in CSS

Support for dialogs in background pages

web_accessible_resources

Manifest “key” property

Content script HTTP(S) requests

Content script environment

Executing code in a web page from content script

Sharing variables between content scripts

Content script lifecycle during navigation

“per-tab” zoom behavior

See {{WebExtAPIRef("tabs.ZoomSettingsScope")}} .

manifest.json keys

The main manifest.json page includes a table describing browser support for manifest.json keys. Where there are caveats around support for a given key, this is indicated in the table with an asterisk “*”. Selecting the asterisk expands the table to display a note explaining the caveat.

The tables are generated from compatibility data stored as JSON files in GitHub.

Native messaging

Connection-based messaging arguments

On Linux and Mac: Chrome passes one argument to the native app, which is the origin of the extension that started it, in the form of chrome-extension://«extensionID/» (trailing slash required). This enables the app to identify the extension.

On Windows: Chrome passes two arguments:

  1. The origin of the extension
  2. A handle to the Chrome native window that started the app

allowed_extensions

App manifest location

App persistence

Data cloning algorithm

Some extension APIs allow an extension to send data from one part of the extension to another, such as {{WebExtAPIRef("runtime.sendMessage()")}} , {{WebExtAPIRef("tabs.sendMessage()")}} , {{WebExtAPIRef("runtime.onMessage")}} , the postMessage() method of {{WebExtAPIRef("runtime.port")}} , and {{WebExtAPIRef("tabs.executeScript()")}} .

The Structured clone algorithm supports more types than the JSON serialization algorithm. A notable exception are (DOM) objects with a toJSON method. DOM objects are not cloneable nor JSON-serializable by default, but with a toJSON() method, these can be JSON-serialized (but still not cloned with the structured cloning algorithm). Examples of JSON-serializable objects that are not structured cloneable include instances of {{domxref("URL")}}  and {{domxref("PerformanceEntry")}} .

Extensions that rely on the toJSON() method of the JSON serialization algorithm can use {{jsxref("JSON.stringify()")}}  followed by {{jsxref("JSON.parse()")}}  to ensure that a message can be exchanged because a parsed JSON value is always structurally cloneable.

In this article

View on MDN