One runtime per page
Every widget on a page shares a single Web Worker and a single Python runtime. Ten editors cost one ~11MB download, not ten.
See two editors share a worker →A code editor that actually runs the code it shows, as one custom element. No backend, no iframe, no sign-up — it all happens in the reader's own browser. Type in the box and press Run.
Python · JavaScript · TypeScript
Real CPython 3.14 via Pyodide — full standard library,
input(), tracebacks, numpy on demand — plus
the browser's own JavaScript engine, and TypeScript with its types
stripped. Each language loads only on the pages that use it.
That snippet blocks on input() — the program waits for you,
the way a terminal does. No cross-origin isolation required.
Every widget on a page shares a single Web Worker and a single Python runtime. Ten editors cost one ~11MB download, not ten.
See two editors share a worker →
A widget can hold a whole small project — flat modules, packages
with __init__.py, data files you open().
Tracebacks name the real file and line.
Python runs in a Worker, so while True: is a stoppable
mistake rather than a dead tab.
Edits persist in IndexedDB, and soft navigation keeps the runtime warm between pages — the first run on a new lesson takes milliseconds, not seconds.
Walk between two lessons →One script tag. CodeMirror is bundled; Python is fetched at runtime.
<script type="module"
src="https://cdn.jsdelivr.net/npm/code-playpad@0.1.3"></script>
<code-playpad height="180">
print("hello from a CDN")
</code-playpad>
Or install it and use the modular build, with CodeMirror as a peer dependency so you never end up with two copies:
npm install code-playpad
React wrapper included — see it here. Works in plain HTML, Astro, Next.js, and anything else that can render an element.