Concepts

How Verklet runs Node.js-style and Python workloads across browser workers, Pyodide, OPFS, service workers, WASM, and server promotion.

Verklet is browser-first. The browser backend is built from browser primitives, each doing one job. None of them is new; the work is in stitching them into something that feels like a real Node and Python host. The server backend adds a managed Linux workspace for workloads the browser cannot run.

Web Workers — process isolation

Every "process" in Verklet is a Web Worker. The main thread doesn't execute user code. It owns the runtime container and the UI; user processes run in workers that get their own message channel, their own stdio streams, and their own crash boundary.

This matters because:

You don't manage workers directly. runtime.spawn() allocates them; process exit reclaims them.

OPFS — persistent storage

The virtual filesystem lives in memory while a session is open. When you pass persistenceKey to Runtime.boot(), Verklet writes a content-addressed snapshot to the Origin Private File System — a per-origin sandbox that survives reloads but is invisible to other sites.

What that gets you:

OPFS support varies. Chromium and Firefox are solid; WebKit is partial. Verklet detects this at boot via capabilities.opfs and degrades to in-memory if necessary — your code runs either way.

Server-runtime persistence uses a managed workspace instead of OPFS. When backend: 'auto' promotes a browser session to the server, Verklet exports a binary VFS snapshot and mounts it into that workspace. Browser-only dependency artifacts such as node_modules are not copied; successful install commands are replayed on the server by default, and explicit server setup can be declared with server.prepare.

Preview routing

When a process inside the runtime opens a port, that port doesn't actually exist at the network level. The browser has no concept of "an HTTP server in a worker." So Verklet uses an isolated preview origin like https://<session>.preview.verklet.com with a service worker and message bridge that routes preview requests into the runtime as in-process function calls.

The upshot:

The hosted boot service returns https://{previewSessionId}.preview.verklet.com as the default preview origin template. If your application uses a Content Security Policy, allow https://*.preview.verklet.com in frame-src or child-src so preview iframes can load. Use runtime.fetchPreview() when your host page needs to inspect preview responses programmatically; it routes inside the runtime instead of relying on cross-origin browser fetches. Corporate firewalls or egress allowlists need the same wildcard hostname.

The preview bridge is registered automatically on Runtime.boot(). If you've disabled service workers in your hosting setup, pass serviceWorker: false and use runtime.fetchPreview() directly.

WebAssembly — the hot paths

Anything that needs to be fast or POSIX-shaped is WASM. The synchronous virtual filesystem (so fs.readFileSync works without yielding to the event loop), the package archive parser, the path-traversal validator, and a handful of binary codecs all live in Rust-built WASM modules.

JavaScript handles policy and orchestration. WASM handles the bytes. This split is why a Node process inside Verklet can call fs and Buffer APIs without the runtime stalling on every read.

Server runtime — Linux when the browser is the wrong host

Python starts in the browser through Pyodide. The server runtime is a managed backend reached through the same SDK. It is used directly with backend: 'server' or automatically with backend: 'auto' when native Python wheels, uv, subprocesses, or native tools need capabilities that do not exist inside a browser worker.

The server backend exposes a remote VFS, process stdout/stderr, process exit events, diagnostics, persistence, and usage events through the same runtime object. From the UI's perspective, the important thing is that the programming model does not split into a separate local API and a separate remote API.

Putting it together

A typical boot looks like this:

From the user's perspective they opened a tab and typed code. From the host's perspective, the runtime pieces clicked together and a browser Node/Python sandbox came up. See the compatibility matrix for what behaviour is wired up today.