Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/content/documentation/develop/browser-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ topic: Develop
tags: [beginner, extensions, webextensions, compatibility, cross-browser]
contributors: [rebloor]
last_updated_by: rebloor
date: 2019-05-27 6:35:30
date: 2026-05-19
---

<!-- Page Hero Banner -->
Expand All @@ -27,10 +27,10 @@ date: 2019-05-27 6:35:30

{% capture content_with_toc %}

While work continues to standardize the APIs used for browser extension development, there remain differences between Chromium-based browserssuch as Chrome, Opera, and the Chromium-based Microsoft Edge—and Firefox. These differences, summarized on this page, include:
Work is progressing to standardize the APIs used for browser extension development. This page summarizes the differences between Firefox and the Chromium-based browsers, such as Chrome, Opera, and Microsoft Edge. These differences include:

- **Namespace**: In Chromium-based browsers, JavaScript APIs are accessed under the `chrome` namespace. In Firefox, they are accessed under the `browser` namespace.
- **Asynchronous APIs**: In Chromium-based browsers, asynchronous APIs are implemented using callbacks. In Firefox, asynchronous APIs are implemented using promise.
- **Namespace**: In Chromium-based browsers, extensions access the JavaScript APIs under the `chrome` namespace. In Firefox (and Safari), extensions access the APIs under the `browser` namespace. However, starting with Chromium 148, Chromium-based browsers also support the `browser` namespace, except for extensions with a DevTools page.
- **Asynchronous APIs**: In Chromium-based browsers, asynchronous APIs are implemented using callbacks. Firefox (and Safari) implement asynchronous APIs using promises. However, with the introduction of Manifest V3, Chromium has been updated to support promises in all APIs except the tools devtools APIs. For more information, see [Chromium issue 41483013: Support Promises on devtools extension API](https://issues.chromium.org/issues/41483013).
- **API support**: Support for JavaScript APIs differs among browsers.
- **Manifest key support**: Support for `manifest.json` keys differs among browsers.
- Variations due to differences in browser behavior.
Expand All @@ -51,13 +51,15 @@ Firefox is the most compliant with the proposed standard, and is, therefore, you

## Namespace

You reference all extensions API functions using a namespace, for example, `browser.alarms.create({delayInMinutes});` would create an alarm in Firefox that goes off after the time specified in `delayInMinutes`.
You reference all extensions API functions using a namespace, for example, `browser.alarms.create({delayInMinutes});` creates an alarm in Firefox that goes off after the time specified in `delayInMinutes`.

There are two API namespaces in use:

- `browser`(the proposed standard) is used in Firefox. For example: `browser.browserAction.setIcon({path: "path/to/icon.png"});`
- `browser` (the proposed standard) is used in Firefox. For example: `browser.browserAction.setIcon({path: "path/to/icon.png"});`
- `chrome` is used in Chromium-based browsers. For example: `chrome.browserAction.setIcon({path: "path/to/icon.png"});`

Starting with Chromium 148, Chromium-based browsers support the `browser` namespace, except for extensions with a DevTools page. This update means all major browsers now support the `browser` namespace. For more information on Chrome support for the `browser` namespace, see [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace).

{% endcapture %}
{% include modules/one-column.liquid,
id: "namespace"
Expand All @@ -74,9 +76,9 @@ There are two API namespaces in use:

JavaScript provides several ways in which to handle asynchronous events. The proposed extensions API standard is to use the promise object. The promise approach provides significant advantages when dealing with chained asynchronous event calls.

Firefox uses the promise object for all asynchronous WebExtensions APIs. Chromium-based browsers use callbacks.
Firefox uses the promise object for all asynchronous WebExtensions APIs. Chromium-based browsers use callbacks. However, with the introduction of Manifest V3, Chromium has been updated to support promises in all APIs except the tools devtools APIs. For more information, see [Chromium issue 41483013: Support Promises on devtools extension API](https://issues.chromium.org/issues/41483013).

As a porting aid, the Firefox WebExtension APIs supports `chrome` using callbacks and `browser` using promise. This means that many Chrome extensions will work in Firefox without changes, unless they are using Chrome specific APIs that don’t exist in Firefox.
As a porting aid, the Firefox WebExtension APIs support `chrome` using callbacks and `browser` using promise. This means that many Chrome extensions work in Firefox without changes, unless they are using Chrome specific APIs that don’t exist in Firefox.

In Chrome, asynchronous APIs use callbacks to return values, and [`runtime.lastError`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/lastError) to communicate errors:

Expand Down Expand Up @@ -196,5 +198,3 @@ You can find more detailed information about the differences in the supported br
%}

<!-- END: Single Column Body Module -->


20 changes: 13 additions & 7 deletions src/content/documentation/develop/manifest-v3-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ contributors: [
willdurand
]
last_updated_by: rebloor
date: 2023-03-03
date: 2026-05-19
---

<!-- Page Hero Banner -->
Expand Down Expand Up @@ -97,7 +97,7 @@ To accommodate this change, provide a local icon and define it in your manifest.
"name": "Search engine",
"search_url": "https://www.searchengine.com/search/?q={searchTerms}",
"keyword": "search",
"favicon_url": "/imager/favicon.ico"
"favicon_url": "/images/favicon.ico"
}
}
```
Expand All @@ -114,7 +114,7 @@ To accommodate this change, provide a local icon and define it in your manifest.

In Manifest V2, an extension requests its host permissions in the manifest.json `permissions` or `optional_permissions` keys. The host permissions defined in the `permissions` key are displayed to the user on installation and granted to the extension permanently.

In Manifest V3, host permissions are defined in the [`host_permissions`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions) and [`optional_host_permissions`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_host_permissions) keys.
In Manifest V3, host permissions are defined in the [`host_permissions`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions) and [`optional_host_permissions`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_host_permissions) keys.

In Firefox 126 and earlier, Manifest V3 host permissions were not granted during installation and were not displayed to the user. From Firefox 127, host permissions listed in `host_permissions` and `content_scripts` are displayed in the install prompt and granted on installation. However, if an extension update grants new host permissions, these are not shown to the user (see [Firefox bug 1893232](https://bugzil.la/1893232)).

Expand Down Expand Up @@ -153,7 +153,8 @@ The features available under the manifest.json key `browser_action` and the `bro
As the old and new key and API are otherwise identical, the changes needed are relatively straightforward and are as follows:

- Rename the manifest.json key 'browser_action' to 'action' and remove any reference to [`browser_style`](#browser-style), like this:
```json

```json
"action": {
"default_icon": {
"16": "button/geo-16.png",
Expand All @@ -172,6 +173,7 @@ As the old and new key and API are otherwise identical, the changes needed are r
}]
}
```

- Update API references from `browser.browserAction` to `browser.action`.
- If used, change `_execute_browser_action` to `_execute_action` in the `commands` manifest key and in the [`menu.create`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/create) and [`menu.update`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/update) API methods (or their aliases `contextMenus.create` and `contextMenus.update`).

Expand Down Expand Up @@ -333,6 +335,7 @@ if (eventPagesSupported) {
### XHR and fetch in content scripts

Cross-origin requests, permitted by extension permissions, using [XHR and fetch](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#xhr_and_fetch) in content scripts are no longer allowed. Instead:

- The destination server should use CORS, or
- The extension has to send a message to the background page (or an extension tab or frame) to ask it to make a request on the content script's behalf.

Expand Down Expand Up @@ -361,8 +364,7 @@ Manifest V3 has a more restrictive content security policy than Manifest V2, thi

Mozilla’s long-standing [add-on policies](/documentation/publish/add-on-policies/) prohibit remote code execution. In keeping with these policies, the [content_security_policy](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy) field no longer supports sources permitting remote code in script-related directives, such as `script-src` or `’unsafe-eval’`. The only permitted values for the `script-src` directive are `’self’` and `’wasm-unsafe-eval’`. `’wasm-unsafe-eval’` must be specified in the CSP if an extension is to use WebAssembly. In Manifest V3, content scripts are subject to the same CSP as other parts of the extension.

The Manifest V3 CSP also includes `upgrade-insecure-requests` by default. For more information, see [
Upgrade insecure network requests in Manifest V3](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#upgrade_insecure_network_requests_in_manifest_v3) in the web extensions content security policy guide.
The Manifest V3 CSP also includes `upgrade-insecure-requests` by default. For more information, see [Upgrade insecure network requests in Manifest V3](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#upgrade_insecure_network_requests_in_manifest_v3) in the web extensions content security policy guide.

Historically, a custom extension CSP required `object-src` to be specified. This is not required in Manifest V3 (and was removed from Manifest V2 in Firefox 106). See [`object-src` in the `content_security_policy` documentation](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy#object-src_directive)). This change makes it easier for extensions to customize the CSP with minimal boilerplate.

Expand Down Expand Up @@ -390,7 +392,11 @@ To migrate your extension, rewrite the manifest.json key [‘web_accessible_reso

### Features already supported by Firefox

As part of its Manifest V3 implementation, Chromium introduces [promise](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-overview#promises) support to many methods with the goal of eventually supporting promises on all appropriate methods. This will provide for greater compatibility between Firefox and Chrome extensions, given that Firefox already supports promises when using the `browser.*` namespace.
Historically, Chrome's extension APIs were exposed only through callback-based interfaces in the `chrome.*` namespace. As part of its Manifest V3 implementation, Chromium introduced support for [promises](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-overview#promises) in their `chrome.*` namespace. By Chromium 148, the `browser.*` namespace is also supported except for extensions with a DevTools page ([Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace)).

Firefox pioneered the `browser.*` namespace, and made the [webextensions-polyfill](https://github.com/mozilla/webextension-polyfill) available for (Chromium) browsers that lacked support for the namespace.

This situation means that all major browsers now support the `browser.*` namespace, improving compatibility among Firefox, Safari, and Chrome extensions.

In Manifest v2, Firefox extensions support the use of the `chrome.*` namespace with APIs that provide asynchronous event handling using callbacks. In Manifest V3, Firefox supports promises for asynchronous events in the `chrome.*` namespace.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ contributors:
kumar303,
yfdyh000,
]
last_updated_by: jennyevans
date: 2019-05-19 11:54:36
last_updated_by: rebloor
date: 2026-05-19
---

<!-- Page Hero Banner -->
Expand All @@ -40,7 +40,13 @@ date: 2019-05-19 11:54:36

{% capture content %}

The browser extension APIs are designed to promote cross-browser compatibility among extensions. The WebExtension APIs is therefore, to a large extent, code-compatible with the [extension API](https://developer.chrome.com/extensions) supported by Google Chrome and Opera. Extensions written for these browsers will, in most cases, run in Firefox with just a few changes. Almost all of the [WebExtension APIs](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API) provide support for callback functions under the `chrome` namespace, the same as Chrome. The only APIs that aren't supported in the `chrome` namespace are those that are intentionally incompatible with Chrome. In those cases, the API documentation page states that support is provided only in the `browser` namespace. The process of porting an extension from Chrome or Opera is, therefore, relatively straightforward:
The browser extension APIs are designed to promote cross-browser compatibility among extensions. The WebExtension APIs are therefore, to a large extent, code-compatible with the [extension API](https://developer.chrome.com/docs/extensions/reference/) supported by Google Chrome and Opera. Extensions written for these browsers, in most cases, run in Firefox with just a few changes.

Starting with Chromium 148, Chrome supports the `browser` namespace and promises (except for extensions with a DevTools page), meaning all major browsers now support the `browser` namespace. For more information, see [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace).

For Chrome extensions that don't use the `browser` namespace, the [WebExtension APIs](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API) provide support for callback functions under the `chrome` namespace.

The process of porting an extension from Chrome or Opera is, therefore, relatively straightforward:

1. Review your use of `manifest.json` features and Chrome extension APIs against the [Chrome incompatibilities reference](https://developer.mozilla.org/Add-ons/WebExtensions/Chrome_incompatibilities). Mozilla provides a service that can help to automate this step within the [Add-on Developer Hub](https://addons.mozilla.org/developers/addon/validate). If you're using features or APIs that aren't supported in Firefox, you might not be able to port your extension.
2. Install your extension in Firefox by using [`about:debugging`](https://developer.mozilla.org/docs/Tools/about:debugging) or the [web-ext tool](/documentation/develop/getting-started-with-web-ext#testing-out-an-extension) (similar to Chrome’s command-line tools).
Expand All @@ -58,5 +64,3 @@ If you use the Chrome command-line option for loading an unpacked extension, che
%}

<!-- END: Single Column Body Module -->


Loading