Supporting Edge, Opera and Brave
Ship an MV3 Chrome extension to Chromium-based browsers: Edge Add-ons ids and review, Opera's add-ons store, Brave and Vivaldi installing from the Chrome Web Store, and the API differences that still matter.
Table of Contents
Your Chrome extension already runs in Edge, Opera, Brave and Vivaldi — they are all Chromium, and most of their users can install from the Chrome Web Store. So why do support tickets mention Edge-specific sign-in failures, Brave users report a feature that never works, and an enterprise customer insists on the Microsoft Edge Add-ons store? Chromium browsers share an engine but not identity services, policy defaults, privacy features or stores. Supporting them well is mostly about knowing those differences. This guide covers each. It belongs to cross-browser API compatibility.
Same engine, different products
Every Chromium-based browser implements the extension APIs from the shared Chromium codebase, so chrome.storage, tabs, scripting, declarativeNetRequest, sidePanel and the rest behave as in Chrome at the same Chromium version. Differences come from what each vendor adds, removes or configures. Google-specific services are the biggest: chrome.identity.getAuthToken is backed by the Google account signed into Chrome and is unavailable or different elsewhere. Privacy-focused browsers change defaults — Brave’s Shields block trackers and some third-party requests that your extension’s pages might make. Stores differ: Edge has its own Add-ons store with its own extension ids; Opera has an add-ons site and can also install from the Chrome Web Store with a helper; Brave and Vivaldi install directly from the Chrome Web Store. And Chromium versions lag Chrome’s by days to weeks, which matters if you depend on brand-new APIs.
Step-by-step: first-class support for Chromium browsers
1. Replace getAuthToken with launchWebAuthFlow
1// sw.js — works in every Chromium browser and in Firefox
2export async function signIn() {
3 const redirect = chrome.identity.getRedirectURL(); // https://<id>.chromiumapp.org/
4 const url = new URL("https://accounts.example.com/oauth/authorize");
5 url.search = new URLSearchParams({ client_id: CLIENT_ID, response_type: "code", redirect_uri: redirect,
6 code_challenge: await pkceChallenge(), code_challenge_method: "S256" });
7 const result = await chrome.identity.launchWebAuthFlow({ url: url.href, interactive: true });
8 return exchangeCode(new URL(result).searchParams.get("code"));
9}
Execution context: the service worker. getAuthToken depends on the Google account signed into Chrome and does not work the same way in Edge, Brave or Opera. launchWebAuthFlow works in all of them because it runs a standard OAuth flow in a browser-managed window. Each store’s build has a different extension id and therefore a different redirect URL — register all of them with your OAuth provider. See choosing between getAuthToken and launchWebAuthFlow.
2. Account for different extension ids per store
1// shared/ids.js
2export const EXTENSION_IDS = {
3 chromeWebStore: "abcdefghijklmnopabcdefghijklmnop",
4 edgeAddons: "ponmlkjihgfedcbaponmlkjihgfedcba",
5 operaAddons: "mnopabcdefghijklmnopabcdefghijkl",
6};
Execution context: shared configuration for your website and backend. Anything that recognises the extension by id — externally_connectable calls from your website, native messaging host manifests, OAuth redirect allow-lists, server-side origin checks — must list every store’s id. A user who installed from Edge Add-ons has a different id from one who installed the same build from the Chrome Web Store in Edge.
3. Publish to Edge Add-ons
1# Edge Add-ons API (v1.1) — upload a new package for an existing product
2curl -X POST "https://api.addons.microsoftedge.microsoft.com/v1/products/$PRODUCT_ID/submissions/draft/package" \
3 -H "Authorization: ApiKey $EDGE_API_KEY" -H "X-ClientID: $EDGE_CLIENT_ID" \
4 -H "Content-Type: application/zip" --data-binary @dist/chrome.zip
Execution context: CI with Partner Center API credentials. The same zip you upload to the Chrome Web Store usually works unchanged. Edge review is separate and has its own policies, notably around privacy disclosures and search-setting changes. Enterprises that manage Edge often allow only Edge Add-ons sources, so a listing there matters for business users. See publishing to Microsoft Edge Add-ons.
4. Test with Brave’s Shields on
1// Detect Brave without user-agent sniffing
2const isBrave = (await navigator.brave?.isBrave?.()) === true;
3if (isBrave) console.info("[env] Brave detected — check Shields interaction with extension pages");
Execution context: an extension page. Brave’s Shields can block requests from extension pages to third-party analytics or CDNs, and its fingerprinting protections alter some web APIs’ results. Detection is useful for diagnostics, not for changing behaviour. Test your extension’s network calls, especially from popups and options pages, with Shields at their default and aggressive settings.
5. Feature-detect new APIs because of version lag
1if (chrome.sidePanel?.setOptions) {
2 await chrome.sidePanel.setOptions({ path: "panel.html", enabled: true });
3} else {
4 await chrome.action.setPopup({ popup: "panel.html" });
5}
Execution context: the service worker. Each browser ships a Chromium version on its own schedule, and some vendors disable or modify specific features. A feature added in Chrome last month may not exist yet in Opera. minimum_chrome_version applies to every Chromium browser (they report Chromium’s version), so it gates installation consistently; feature detection covers the rest.
6. Write support documentation per browser
Users in non-Chrome browsers often cannot find the equivalent of Chrome’s menus: where the extensions page is (edge://extensions, brave://extensions, opera://extensions), how to pin the toolbar icon, where site access controls live. A short per-browser section in your help pages — with the browser’s own URL schemes and screenshots — removes most “it does not work in Edge” tickets.
7. Track usage by browser
1const brand = navigator.userAgentData?.brands
2 ?.map((b) => b.brand)
3 .find((b) => /Edge|Opera|Brave|Vivaldi|Chrome/.test(b)) ?? "other";
Execution context: the service worker, feeding consented, aggregate usage metrics. userAgentData.brands lists the browser’s brand (Brave reports itself here only in some versions). Knowing that, say, 18% of active users are on Edge justifies the time to maintain an Edge Add-ons listing and test there.
Common mistakes
- Relying on
getAuthToken. Sign-in breaks for every non-Chrome Chromium user. - One id in your backend. Edge and Opera store installs have different ids.
- Ignoring privacy features. Brave blocks third-party requests your extension pages may need.
- Assuming the latest Chromium. Vendors lag; feature-detect new APIs.
- Chrome-only help docs. Users cannot find the equivalent menus.
Cross-browser variation
- Edge: Edge Add-ons store with its own id and review; strong enterprise policy support; no Google identity.
- Opera: Opera add-ons store; can also install from the Chrome Web Store with a helper extension; its own sidebar features.
- Brave / Vivaldi: install from the Chrome Web Store with Chrome’s id; Brave’s Shields and fingerprinting protections affect web APIs and requests.
Verification
- Install from each store and confirm
chrome.runtime.idmatches the id registered with your OAuth provider and website. - Sign in from Edge, Brave and Opera using
launchWebAuthFlow. - Test the popup and options page in Brave with Shields on; confirm no blocked requests break features.
- Load the extension in the oldest Chromium version among your target browsers and confirm feature detection handles missing APIs.
FAQ
Do I need separate builds for Edge or Opera?
Usually not. The same package works; only the store listing and the resulting id differ.
Can Edge users install from the Chrome Web Store?
Yes, after enabling “Allow extensions from other stores” in Edge. Many enterprise policies disable that, which is why an Edge Add-ons listing matters.
Does Brave support all MV3 APIs?
Brave follows Chromium closely, but some features are modified or disabled for privacy. Feature-detect and test.
Related
- Chrome vs Firefox vs Safari API gap reference — the non-Chromium gaps.
- Publishing to Microsoft Edge Add-ons — the Edge store in detail.
- Fixing OAuth redirect URI mismatches — registering every id’s redirect.
- Cross-browser API compatibility — the parent topic.