browser-support
Browser support
Which browsers Verklet runs in, what headers your page must serve, and what degrades when isolation isn't available.
Verklet uses SharedArrayBuffer for its synchronous virtual filesystem,
which means your page must be cross-origin isolated. Without the
right headers, the runtime degrades to a partial mode or refuses to boot.
Required headers
Your page must respond with:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
…and every same-origin asset must respond with:
Cross-Origin-Resource-Policy: same-origin
Once all three are present, globalThis.crossOriginIsolated evaluates to
true and SharedArrayBuffer becomes available.
Firefox is strict about CORP. Without Cross-Origin-Resource-Policy: same-origin on every sub-resource, Firefox blocks access to
SharedArrayBuffer even when the page itself is cross-origin isolated.
Chromium tolerates the omission today; Firefox does not. Set CORP
everywhere.
Configuring Next.js
// next.config.ts
export default {
async headers() {
return [
{
source: '/your-runtime-route/:path*',
headers: [
{ key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },
{ key: 'Cross-Origin-Embedder-Policy', value: 'require-corp' },
],
},
{
source: '/_next/static/:path*',
headers: [
{ key: 'Cross-Origin-Resource-Policy', value: 'same-origin' },
],
},
];
},
};
Scope the COOP / COEP headers to the routes that actually need Verklet —
they break third-party <iframe> and <img> embeds that don't return
CORP headers themselves.
Browser matrix
| Feature | Chromium | WebKit | Firefox |
|---|---|---|---|
| Boot runtime | supported | supported | supported |
| Spawn Node process | supported | supported | supported |
Synchronous fs from worker (SyncVfs / SAB) | supported | supported | supported |
| OPFS project persistence | supported | partial¹ | supported |
| OPFS persistence: reload + restore | supported | partial¹ | supported |
| OPFS persistence: cross-tab handoff | supported | unknown² | unknown² |
| Service Worker preview routing | supported | unknown² | unknown² |
| HMR / WebSocket preview bridge | supported | unknown² | unknown² |
Footnotes
-
WebKit OPFS — Real Safari supports OPFS, but Playwright's WebKit build throws
UnknownErroron the firstnavigator.storage.getDirectory()call. The runtime detects this via an availability probe at boot and setscapabilities.opfs = falserather than crashing. Persist+restore skips cleanly when OPFS is unavailable. -
Unknown — The feature has not yet been exercised by the cross-browser smoke harness. Behaviour may differ from Chromium; explicit testing is needed before marking the cell
supportedorpartial.
Detecting capabilities
If you need to render a fallback when the host can't support Verklet:
import { detectCapabilities } from '@verklet/sdk';
const caps = await detectCapabilities();
if (!caps.crossOriginIsolated || !caps.sharedArrayBuffer) {
// show a "open in a modern browser" message, or a static fallback
}