Extensions built with WebExtension APIs are designed to be compatible with Chrome and Opera extensions: as far as possible, extensions written for those browsers should run on Firefox with minimal changes.
However, Firefox currently has support for only a limited set of the features and APIs supported by Chrome and Opera. We're working on adding more support, but many features are not yet supported, and we may never support some.
This article lists all features and APIs that are fully or partially supported in Firefox Developer Edition. Where a feature is partially supported, we've indicated what the gaps are.
You should assume that features and APIs not listed here at all are not yet supported.
JavaScript APIs
Callbacks and the chrome.* namespace
In Chrome, extensions access privileged JavaScript APIs using the chrome
namespace:
chrome.browserAction.setIcon({path: "path/to/icon.png"});
Firefox extensions access the equivalent APIs using the browser
namespace:
browser.browserAction.setIcon({path: "path/to/icon.png"});
Many of the APIs are asynchronous. In Chrome, asynchronous APIs use callbacks to return values, and runtime.lastError
to communicate errors:
function logCookie(c) {
if (chrome.extension.lastError) {
console.error(chrome.extension.lastError);
} else {
console.log(c);
}
}
chrome.cookies.set(
{url: "https://developer.mozilla.org/"},
logCookie
);
The equivalent WebExtensions APIs use promises instead:
function logCookie(c) {
console.log(c);
}
function logError(e) {
console.error(e);
}
var setCookie = browser.cookies.set(
{url: "https://developer.mozilla.org/"}
);
setCookie.then(logCookie, logError);
As a porting aid, the Firefox implementation of WebExtensions supports chrome
and callbacks as well as browser
and promises. This means that many Chrome extensions will just work in Firefox without any changes. However, this is not part of the WebExtensions standard, and might not be supported by all compliant browsers.
If you do write your extension to use browser
and promises, then we've also developed a polyfill that will enable it to run in Chrome: https://github.com/mozilla/webextension-polyfill.
Partially supported APIs
The page Browser support for JavaScript APIs includes compatibility tables for all APIs that have any support in Firefox. Where there are caveats around support for a given API item, this is indicated in these tables with an asterisk "*" and in the reference page for the API item, the caveats are explained.
These tables are generated from compatibility data stored as JSON files in GitHub.
The rest of this section describes compatibility issues that are not already captured in the tables.
notifications
- For
notifications.create(), with the "basic"
type
,iconUrl
is optional in Firefox. It is required in Chrome. - Notifications are cleared immediately when the user clicks on them. This is not the case in Chrome.
- If you call
notifications.create()
more than once in rapid succession, Firefox may end up not displaying any notification at all. Waiting to make subsequent calls until within thechrome.notifications.create() callback
function is not a sufficiently long delay to prevent this from happening.
tabs
-
In Firefox, relative URLs passed into
tabs.executeScript()
ortabs.insertCSS()
are resolved relative to the current page URL. In Chrome, these URLs are resolved relative to the extension's base URL. 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
- In Firefox, querying tabs by URL with
tabs.query()
requires"tabs"
permission. In Chrome, it's possible without the"tabs"
permission but will limit results to tabs whose URLs match host permissions. - In Firefox, the
tabs.remove()
promise is fulfilled after thebeforeunload
event while in Chrome the callback does not wait forbeforeunload
.
webRequest
- In Firefox requests can be redirected only if their original URL uses the
http:
orhttps:
scheme.
windows
- In Firefox
onFocusChanged
will trigger multiple times for a given focus change.
Planned APIs
We don't fully support the following APIs, but plan to do so, soon:
This doesn't mean that these are the only additional APIs we will support, but that they are our current priorities.
Miscellaneous incompatibilities
URLs in CSS
Firefox resolves URLs in injected CSS files relative to the CSS file itself, rather than to the page it's injected into.
Additional incompatibilities
Firefox does not support using alert()
, confirm()
, or prompt()
from background pages.
web_accessible_resources
In chrome, when a resource is listed in web_accessible_resources, it is accessible as chrome-extension://<your-extension-id>/<path/to/resource>. The extension ID is fixed for a given extension.
Firefox implements it otherwise, using a random UUID that changes for every instance of Firefox: moz-extension://<random-UUID>/<path/to/resource>. This randomness can prevent you from doing a few things, such as add your specific extension's URL to another domain's CSP policy.
Manifest "key" property
When working with an unpacked extension, Chrome allows for a "key" property to be added to the manifest to pin the extension ID across different machines. This is mainly useful when working with web_accessible_resources. Since Firefox uses random UUIDs for web_accessible_resources, this property is unsupported.
manifest.json features
Fully supported keys
applications
browser_action
default_locale
description
icons
manifest_version
name
page_action
version
web_accessible_resources
Partially supported keys
background
Firefox does not support the "persistent"
property. Background scripts stay loaded all the time.
chrome_settings_overrides
In Firefox, only "homepage" is supported.
chrome_url_overrides
If two or more extensions both define a custom new tab page, then in Firefox the first extension to run wins. In Chrome, the last extension wins.
commands
Firefox does not support:
global
- any of the media keys: "MediaNextTrack", "MediaPlayPause", "MediaPrevTrack", "MediaStop"
content_scripts
In Firefox, content scripts declared in the manifest will be injected into existing tabs on each extension load. In Chrome, content scripts do not apply to tabs already open when the extension is loaded.
content_security_policy
Firefox does not support:
- "http://127.0.0.1" or "http://localhost" as script sources: they must be served over HTTPS.
options_ui
Firefox does not support:
chrome_style
permissions
Firefox does not support the following permissions:
background
geolocation
unlimitedStorage
Obviously, it doesn't support permissions for APIs that are themselves not supported.
protocol_handlers
This key is not supported in Chrome.
incognito
Firefox does not support the following incognito (private browsing) modes:
split
Native messaging
Command-line 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: chrome-extension://[extensionID]
. This enables the app to identify the extension.
On Windows, Chrome passes two arguments: the first is the origin of the extension, and the second is a handle to the Chrome native window that started the app.
allowed_extensions
In Chrome, the allowed_extensions
key in the app manifest is called allowed_origins
instead.
App manifest location
Chrome expects to find the app manifest in a different place. See Native messaging host location in the Chrome docs.