Python
npm install @kadal/deck-pythonregisterLazyRenderer("python", () => import("@kadal/deck-python").then((m) => m.pythonRenderer));def deck_mount(host, props): return Ticker(host, props) # with deck_update(props) and deck_destroy()import { deckPython } from "@kadal/deck-python/build";
<Island framework="python" load={() => import("./ticker.py?raw").then((m) => deckPython(m.default))} props={{ data }}/>A Python island is source text. Python has no build step: CPython compiled to WebAssembly reads
source at runtime, as on a server. So the island is handed a string, ?raw is the whole pipeline, and
the renderer runs it.
Three things with no equivalent elsewhere
Section titled “Three things with no equivalent elsewhere”destroyis reserved.PyProxy.destroy()is the proxy’s own lifetime method and shadows a Python method of the same name — the island’s teardown would silently never run. The agreement is thereforedeck_mount/deck_update/deck_destroy.- Proxies are freed by hand, in both directions; garbage collection can’t cross the boundary, and a leak lives in WebAssembly memory where no browser tool shows it.
getattr(js.window, "x", None). Pyodide raisesAttributeErrorwhere JavaScript givesundefined.
One interpreter is shared and not torn down when the last island leaves — about six megabytes is too
much to pay twice — but each island runs in its own namespace, so two islands defining deck_mount
stay two islands. It is the only renderer that needs the network: the Pyodide URL is pinned, because an
interpreter that changes under a deck is a talk that breaks on stage. Expect a Python island to start a
few seconds after the others — that is the download.