Browser support

Which browsers the browser backend runs in, what headers your page must serve, and what degrades when isolation isn't available.

The browser backend uses SharedArrayBuffer for its synchronous virtual filesystem, which means your page must be cross-origin isolated. Without the right headers, the browser runtime degrades to a partial mode or refuses to boot.

The server backend does not depend on browser OPFS or SharedArrayBuffer, but the page still needs normal browser support for the SDK, fetch, and WebSocket transport.

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.

Preview CSP

Runtime previews use isolated subdomains under https://*.preview.verklet.com. If your CSP restricts frames, add that wildcard to frame-src and, for older browsers, child-src. SDK calls through runtime.fetchPreview() are routed inside the runtime and do not require browser network access to the preview domain.

Browser matrix

FeatureChromiumWebKitFirefox
Boot runtimesupportedsupportedsupported
Spawn Node processsupportedsupportedsupported
Spawn Python process (Pyodide)supportedunknown²unknown²
Synchronous fs from worker (SyncVfs / SAB)supportedsupportedsupported
OPFS project persistencesupportedpartial¹supported
OPFS persistence: reload + restoresupportedpartial¹supported
OPFS persistence: cross-tab handoffsupportedunknown²unknown²
Service Worker preview routingsupportedunknown²unknown²
HMR / WebSocket preview bridgesupportedunknown²unknown²

Footnotes

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
}