capnwasm dynamic schema demo

Runtime schema, no generated reader/builder. This is the path for tenant-uploaded schemas, admin tools, schema explorers, or anything where the shape arrives after the app ships.

Live result

The browser defines a User schema as plain JS data, builds Cap'n Proto bytes, decodes only selected fields with pick(["id", "name", "active"]), then POSTs the bytes to /api/echo. The Worker decodes and re-encodes the same wire shape.

Loading wasm runtime…

The whole demo

import { load } from "capnwasm/browser";
import { defineSchema, buildDynamic, openDynamic } from "capnwasm/dynamic";

const User = defineSchema({
  id:         { kind: "uint64", offset: 0 },
  name:       { kind: "text",   slot: 0 },
  email:      { kind: "text",   slot: 1 },
  joinedAtMs: { kind: "uint64", offset: 8 },
  active:     { kind: "bool",   bitOffset: 128 },
  avatar:     { kind: "data",   slot: 2 },
}, { dataWords: 3, ptrWords: 3 });

const cpp = await load();
const bytes = buildDynamic(cpp, User)
  .fromObject({ id: 42n, name: "Dynamic Ada", active: true, avatar })
  .finalize();

const picked = openDynamic(cpp, User, bytes).pick(["id", "name", "active"]);
const echoed = await fetch("/api/echo", { method: "POST", body: bytes }).then(r => r.arrayBuffer());
const roundTrip = openDynamic(cpp, User, new Uint8Array(echoed)).toObject();

When to use dynamic vs codegen

dynamiccodegen
Schema known at build timeworkspreferred
Schema arrives at runtimeonly optionnot applicable
Read arbitrary field subsetpick(names)works
Hot typed pathslower per fieldfaster