Firefox Manifest V3 vs Chrome Manifest V3: Key Implementation Differences
Manifest V3 is the current extension platform for both Chrome and Firefox, but the two browsers implemented it differently in ways that matter significantly for content-blocking extensions and developers targeting both platforms. The headline divergence: Firefox preserved webRequestBlocking, the capability that Chrome removed, which is why uBlock Origin maintains full functionality in Firefox MV3 while being substantially limited in Chrome MV3.
Understanding the differences requires understanding why MV3 exists, what changes it mandated, and which of those changes Firefox chose not to adopt or adopted differently.
Why MV3 Happened
Google announced Manifest V3 in 2018 with stated goals: improved performance (replace persistent background pages with event-driven service workers), improved privacy (extensions can’t observe network traffic in real time), and improved security (ban remotely-hosted code). The Chrome developer blog covers the migration.
Privacy and security researchers quickly pointed out that the performance and security goals were real but the “privacy” goal of removing webRequestBlocking had the side effect of preventing effective content-blocking extensions. declarativeNetRequest, the replacement, gives extensions a fixed-size ruleset compiled in advance; webRequest (with blocking) let extensions observe every request and make dynamic, context-aware blocking decisions.
Firefox publicly disagreed with the webRequest removal decision and committed to keeping it.
The webRequest Divergence
Chrome MV3: webRequest is available in read-only mode (can observe requests, cannot block or modify them). To block requests, extensions must use declarativeNetRequest (DNR), which requires pre-compiled rulesets with a maximum of 30,000 static rules and 5,000 dynamic rules (extendable with additional ruleset files).
Firefox MV3: webRequest with webRequestBlocking permission is available. Extensions can observe, block, and modify requests dynamically, the same as in MV2.
The practical consequence: uBlock Origin’s “medium mode” (blocking all third-party scripts by default and allowing exceptions per-site) requires dynamic blocking decisions based on script origin and context. This is straightforward with webRequestBlocking; it can’t be replicated with declarativeNetRequest rulesets because the blocking logic depends on per-request context that static rules can’t express.
Gorhill (uBlock Origin’s developer) maintains separate builds for Chrome and Firefox. The Firefox version has the full feature set. The Chrome version (uBlock Origin Lite) is a pared-down declarativeNetRequest-based version that can’t do dynamic filtering.
Background Pages vs Service Workers
Chrome MV3: Background pages are replaced by service workers. Service workers stop when idle (typically after 30 seconds) and restart on demand. This means:
- In-memory state is lost when the worker stops
- No persistent connections (WebSockets, long-lived port connections) survive worker stops
- Long-running operations must be offloaded to alarms,
chrome.storage, or other persistent mechanisms
Firefox MV3: Supports both background service workers and background pages. Firefox also introduced “Manifest V3 with non-persistent background pages” — a compromise where the background script is event-driven like a service worker but doesn’t follow the full service worker lifecycle. Extensions can migrate gradually.
The implication for extension developers: code written for Chrome’s service worker lifecycle works in Firefox too. But Firefox offers more flexibility, and Firefox’s MV3 documentation at developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions describes options that don’t exist in Chrome.
declarativeNetRequest: What Both Browsers Support
Both browsers support declarativeNetRequest for static blocking rules. The rule format is the same; the limits differ slightly:
- Static rulesets: declared in manifest, loaded at install time. Up to 30,000 rules per Chrome (though extensions can have multiple rulesets); Firefox has similar limits.
- Dynamic rules: set programmatically at runtime via
chrome.declarativeNetRequest.updateDynamicRules(). Chrome: 5,000. Firefox: 5,000. - Session rules: temporary rules cleared when the browser restarts. Same API, similar limits.
For extensions that can express their blocking logic as static rules — simple domain blocklists, known ad-server domains — declarativeNetRequest is actually more efficient than webRequest because the blocking happens in the browser’s network layer before JavaScript is invoked. uBlock Origin’s default filter lists could partially work in DNR, but the advanced filtering logic can’t.
Remotely Hosted Code
Chrome MV3: Bans all remotely hosted code. Extensions cannot fetch and execute JavaScript from external servers. All logic must be bundled in the extension package.
Firefox MV3: Same restriction. This is one area where both browsers aligned, and the security argument is strong. Remotely hosted code was a vector for malicious extension updates that bypassed store review.
User scripts (via Greasemonkey/Tampermonkey) are a partial exception — the user deliberately installs scripts from external sources. Browser extensions themselves cannot fetch and run code they didn’t ship with.
Promises vs Callbacks
Chrome MV3: Chrome’s extension APIs now support Promise-based returns for most APIs, alongside the older callback style.
Firefox: Has used browser.* with Promises natively. Also accepts chrome.* calls for compatibility. The browser namespace is strictly Promise-based; the chrome namespace in Firefox supports callbacks for compatibility.
For new code, write with async/await using either browser.* or chrome.*. Mozilla’s webextension-polyfill provides a Promise wrapper for the chrome.* namespace on Chrome, enabling consistent browser.* style across both.
Content Script Execution World
Both browsers support injecting content scripts into the “MAIN” world (the page’s JavaScript scope) or the default “ISOLATED” world (the content script’s isolated scope). The Chrome documentation covers this. Firefox added support for world: "MAIN" in content script execution as of Firefox 128.
How to Target Both Browsers
The practical approach for a cross-browser extension:
- Write against the
browser.*API using webextension-polyfill. - Use
declarativeNetRequestfor blocking rules that can be expressed as static rules — they’ll work efficiently in both browsers. - If your extension requires dynamic blocking (
webRequestBlocking), use feature detection and fall back gracefully in Chrome:
if (chrome.webRequest && chrome.declarativeNetRequest) {
// Chrome MV3: use DNR only
} else if (browser.webRequest) {
// Firefox: can use blocking webRequest
}
- Handle service worker lifecycle in Chrome (state persistence via storage, no assumption of in-memory state surviving idle periods). This also works correctly in Firefox.
FAQ
Is uBlock Origin the only extension significantly affected by the Chrome MV3 webRequest change? No, but it’s the most visible. Privacy Badger, most custom content-blocking extensions, and any extension that makes dynamic per-request decisions based on context are affected. Extensions that only block a fixed domain list work fine with declarativeNetRequest.
Will Firefox change its position on webRequestBlocking?
Mozilla’s stated position as of 2026 is to maintain webRequestBlocking support to preserve content-blocking extension capability. They documented this as a deliberate deviation from Chrome’s MV3 spec. Nothing in their public communications suggests they’re moving to align with Chrome on this.
Does Chrome’s removal of webRequestBlocking affect Safari extensions? Safari uses a different extension API (Safari Web Extensions, based on WebExtensions but with differences) and independently removed webRequest blocking capability earlier than Chrome. Safari has always used a more restricted content blocking model.
Is Manifest V2 completely gone from Chrome? Google began disabling MV2 extensions in the Chrome Web Store in 2024, starting with the Canary/Dev/Beta channels. MV2 extensions in the store are being phased out for the Stable channel. Enterprise installations can use policy to maintain MV2 extensions longer. New MV2 submissions to the Chrome Web Store are no longer accepted.