Should You Enable COOP/COEP for SharedArrayBuffer in Firefox? A Decision Guide
SharedArrayBuffer in Firefox requires cross-origin isolation. Decide whether COOP/COEP headers are worth the compatibility cost, or fall back to postMessage.
16 Aug 2026, 05:12 UTC

The real constraint: isolation before shared memory
Your Firefox web app needs high-throughput threaded work, and SharedArrayBuffer (SAB) looks like the fastest way to share memory between the main thread and workers. But in Firefox, SAB is not available on ordinary pages. The browser gates it behind cross-origin isolation, which you turn on by sending Cross-Origin-Opener-Policy (COOP) and Cross-Origin-Embedder-Policy (COEP) response headers. The engineering decision is not whether SAB is fast—it is whether your site can survive the isolation rules that come with it.
Decision and constraints
Use SAB in Firefox only if you control the top-level document response headers and can make every embedded frame, image, script, and media request isolation-compatible. If your app depends on third-party embeds, ad slots, OAuth popups, or a strict Content-Security-Policy that makes COEP risky, keep the app non-isolated and move data with postMessage and structured clone—the browser's built-in deep-copy mechanism.
This guide assumes you serve over HTTPS, control response headers, and support modern Firefox release or ESR builds. It does not cover non-browser embeddings.
Compare the supported options
| Option | Firefox behavior to verify | Use when |
|---|---|---|
No SAB; workers + postMessage | No special headers; SAB stays undefined | Third-party embeds, ads, OAuth popups, or strict CSP make COEP risky |
COOP: same-origin + COEP: require-corp | crossOriginIsolated is true; SAB is defined | You control all origins/resources and need shared memory |
COOP: same-origin-allow-popups + COEP: require-corp | Isolation with popup exceptions | You need OAuth/payment popups but still want SAB |
Trade-offs that decide the choice
COEP: require-corp blocks cross-origin images, media, and iframes unless they opt in with Cross-Origin-Resource-Policy (CORP) or CORS. A single third-party player or tracking pixel without those headers can break the page. COOP: same-origin severs window references to cross-origin openers, which commonly breaks OAuth and payment flows that rely on window.opener handles. same-origin-allow-popups keeps popups usable but still isolates your opener from them.
Shared memory reduces copying, but it increases your correctness and security burden: you now coordinate access across threads and must ensure no cross-origin document can read the buffer. If your workload is bursty or your payloads are large but infrequent, transferring an ArrayBuffer to a worker and back is often cheaper than the operational cost of isolation. Structured clone copies data, but modern Firefox optimizes transferable objects so the main thread is not blocked for the full copy. Measure before you commit to shared memory.
Concrete implementation
On the top-level HTML document, send the isolation headers. For cross-origin assets that do not need cookies, add CORP on the asset response; otherwise serve them with CORS.
# Main document response headers
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
# Example cross-origin, no-cookie asset response
Cross-Origin-Resource-Policy: cross-origin
In JavaScript, never feature-detect SharedArrayBuffer alone. An undefined SAB on a non-isolated page must fall back, not throw.
const canUseSAB =
self.crossOriginIsolated &&
typeof SharedArrayBuffer === 'function';
if (canUseSAB) {
const worker = new Worker('worker.js');
const sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
} else {
// fallback: postMessage + structured clone
}
In the worker, verify the buffer arrives intact:
// worker.js
self.onmessage = (e) => {
const buf = e.data;
const ok =
buf instanceof SharedArrayBuffer &&
buf.byteLength === 1024;
self.postMessage({ ok, byteLength: buf.byteLength });
};
Validate in Firefox before you commit
Open DevTools on the deployed page and evaluate the following in the console. These checks require no special permissions beyond opening DevTools itself.
self.crossOriginIsolated
typeof SharedArrayBuffer
self.origin
Confirm that crossOriginIsolated is true, typeof SharedArrayBuffer is 'function', and self.origin matches your site. In the Network panel, confirm the main document response carries COOP and COEP, and that every subresource is same-origin, CORS-enabled, or CORP-enabled. Run the worker snippet above—replace worker.js with your actual script path and adjust the buffer size to your workload—and confirm no SecurityError and a correct byteLength.
Test in a clean profile with default settings and in private windows. If you support ESR, compare behavior there as well; header and SAB availability are version- and channel-sensitive.
Rollback
Because response headers change server state, plan a rollback. Remove Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy from the document response, purge any CDN cache, and verify in DevTools that crossOriginIsolated is false and typeof SharedArrayBuffer is 'undefined'.
Limitations
COEP: require-corpcommonly breaks third-party iframes, embedded players, and images loaded without CORS or CORP.COOP: same-origincan break OAuth/payment flows that rely on window handles; prefersame-origin-allow-popupsonly after testing.- Header changes may be cached by CDNs; roll out with cache-busting and verify the document, not just the JS bundle.
- Do not assume SAB availability from desktop release alone—verify on the exact Firefox builds you support.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.