Docs / Runtime / Wurster Web

Wurster Web

Wurster Web is the browser-hosted Wurster runtime family. Its distributable surface is intentionally dependency-free:

wurster.min.js
wurster-sw.js
wurster-embed.js
wurster-embed-host.html

The core runtime uses a service worker to give each Wurst a virtual application resource surface while the visible Wurst runs in a sandboxed iframe. Normal relative HTML/CSS/JavaScript URLs therefore keep working inside a Wurst.

0.20.0 runtime surface

Wurster Web can:

A remote Wurst remains read-only at its origin. Browser writes belong to the current Wurster session until the user exports a new Wurst snapshot.

The simple embed

The CDN-facing integration is deliberately image-like:

<script type="module" src="https://cdn.example/wurster/wurster-embed.js"></script>

<wurst-embed src="./media/example.wurst"></wurst-embed>

wurst-embed is a standards-based Custom Element. Custom Element names require a hyphen, which is why the element is not simply <wurst>.

Size it with normal CSS:

wurst-embed {
  width: 720px;
  height: 480px;
}

Optional embedded WurstKey

A developer may intentionally publish or share a key together with an embed:

<wurst-embed
  src="./demos/client-preview.wurst"
  wurstkey="wurstkey-v1-....">
</wurst-embed>

This is useful for demos, controlled previews, puzzles or any case where encryption is desired as packaging/access behavior but the embedding page is intentionally allowed to know the key.

The wurstkey attribute is part of the host page DOM. Any script trusted by that page can read it. Do not use the attribute when the embedding page itself must not know the secret.

If the attribute is omitted:

The key is used by the Wurster Web host and is never exposed as window.wurst data to the Wurst application.

Why the embed does not install a service worker on your site

A normal service worker belongs to the origin and scope that registered it. A third-party CDN script should not ask every embedding site to install a root-level Wurster service worker.

<wurst-embed> therefore creates an isolated Wurster host iframe on the Wurster distribution origin. The parent page reads the configured Wurst source and answers bounded byte-range requests over a MessageChannel:

embedding page
    |
    | <wurst-embed src="./demo.wurst">
    v
Wurster embed element
    |
    | bounded byte ranges
    v
isolated Wurster host iframe
    |
    +-- Wurster Web
    +-- Wurster service worker on the host origin
    +-- sandboxed Wurst application iframe

If the Wurst server supports HTTP Range, the parent streams only the required ranges. If the server ignores Range but permits the fetch, the embed falls back to a local Blob source.

Cross-origin Wurst URLs still follow ordinary browser CORS rules.

Direct JavaScript API

Applications that host Wurster Web themselves may still use the lower-level API:

<script type="module">
  import { WursterWeb } from "/wurster.min.js";

  const session = await WursterWeb.open(fileOrUrl, {
    serviceWorkerUrl: "/wurster-sw.js",
    serviceWorkerScope: "/"
  });

  await session.mount("#wurst-stage");
</script>

A WurstKey can be supplied programmatically too:

const session = await WursterWeb.open(fileOrUrl, { wurstKey });

Partial application protection

Partial application protection already exists in WRST v7 and MeatGrinder:

src/       public application shell
sealed/    developer-owned WurstKey content

The public entry runs without a WurstKey. If it later exposes:

<wurster-auth type="wurstkey" purpose="application"></wurster-auth>

This explicit control is optional. A fetch/navigation for a protected application resource also triggers the same Wurster-owned unlock UI automatically. The pending resource continues after a valid key; choosing Not now leaves the public shell running and rejects only that protected request.

Wurster Web opens the actual key-entry surface outside the Wurst application frame. On success the encrypted application resources become readable through their normal logical paths.

If a protected resource is requested before the application has unlocked, the runtime reports the resource as locked rather than returning ciphertext or silently weakening protection.

Fully sealed applications

A fully sealed Wurst hides its original application entry and logical application paths behind an encrypted wurst/sealed-app-map-1 map. Wurster Web now opens that map with the same portable WurstKey/AES-256-GCM semantics as Desktop Wurster and only then starts the real application entry.

No application HTML executes before a valid WurstKey is available.

URL semantics

A Wurst is still a web application internally. Static application resources use normal relative URLs:

<script src="./app.js"></script>
<link rel="stylesheet" href="./style.css">
<img src="./assets/pig.png">

For mutable /data resources the Wurst asks the runtime:

video.src = wurst.fs.url('/data/videos/flight.mp4');

The returned URL is runtime-owned and opaque.

WurstFS on the web

The web runtime does not pretend it can silently overwrite a remote server object or an arbitrary local file. Instead it exposes a writable session overlay:

remote/local Wurst base     read
browser session overlay     read/write
snapshot export             new standalone .wurst

IndexedDB may be used as an implementation backing store, but it is not part of the portable Wurst persistence contract.

Wurster online viewer

The Wurster site consumes the same generated web-runtime distribution and exposes /viewer/ as a general browser Wurst viewer. A user can drag a .wurst or .wrst file onto the page and run it without installing Desktop Wurster.

The viewer is intentionally built on <wurst-embed> rather than a separate private runtime. This keeps the public embed path and the official viewer on the same implementation.

Remaining browser parity work

0.20.0 completes WurstKey application execution, but not every Desktop trust/auth feature is browser-equivalent yet.

Still before 1.0:

The runtime must report unsupported behavior honestly rather than pretending that browser and desktop capabilities are identical.

WRST.IO Authority trust

The Web distribution contains the same pinned public WRST.IO Root and Root-signed trust bundle as Desktop Wurster. wurst/publisher-certificate-3 verified claims are checked locally through Root → issuer → publisher after the package signature verifies. This does not require a browser request to authority.wrst.io; live DNS identity remains a separate optional trust route.