PyScript local development

August 14, 2026 · View on GitHub

Who: You run or hack the browser demo locally, or port examples to PyScript.

Prerequisites: Python 3 on your PC (for http.server only).

Live demo (online)

PyDevices.github.io/pydevices-examples/pyscript/

PageURL
Calculatorpyscript/micropython.html?modules=calc_graphics,calc_engine
Editorpyscript/editor.html
REPLpyscript/repl.html
Asyncpyscript/async.html
DOMpyscript/dom.html
Pyodide (modules / manifests)pyscript/pyodide.html?modules=calc_graphics,calc_engine · manifests=chango

Run locally

--8<-- "_snippets/pyscript-local.md"

Examples in the browser gallery are copied to the deploy site and installed from the same origin on GitHub Pages. Locally, tools/serve.py serves your working tree — gallery pages load lib/examples/ via .site/pyscript/micropython.html?modules=… / ?manifests=… (MicroPython). Use .site/pyscript/pyodide.html with the same query shape for Pyodide smoke tests (MIP JSON under packages/ via the .site/pyscript/packages symlink; no ?packages=); it is not wired into the gallery. Non-gallery pages (repl.html, editor.html, async.html, dom.html) may still use github: installs.

Minimal teaching shells

These tiny pages sit beside the gallery loaders and each highlight one PyScript idea:

PageFeature
editor.htmltype="mpy-editor" with hidden setup + shared env — editable lesson + Run
repl.htmlterminal worker + code.interact
async.htmlasync / await animation that yields to the browser
dom.htmlHTML button → Python via create_proxy

REPL: worker vs main thread

repl.html uses <script type="mpy" … terminal worker>. The worker attribute runs MicroPython off the page's main thread so:

  • input() works inside the terminal (no browser prompt() dialog)
  • Long-running or blocking REPL code does not freeze the tab UI

Without worker, a MicroPython terminal still works, but input() falls back to the browser's native dialog, and a tight loop can freeze the page. Prefer worker for REPL-style shells unless you have a specific reason to stay on the main thread.

Gallery loaders and the async.html / dom.html shells stay on the main thread because they drive the canvas and DOM listeners directly (same pattern as micropython.html).

asyncio requirement

PyScript runs on asyncio. Prefer runtime.run_forever() with on / on_tick callbacks so demos stay responsive. See PyScript asyncio guide, or open async.html for a minimal bouncing-square loop.

Regenerate the card list with python scripts/gallery_generator.py. Every example entry under lib/examples/ is included by default.

MarkerEffect
# deps: …Logical packages → ?deps= via url_maker (MIP on MicroPython, micropip on Pyodide)
# modules: …Extra example .py stems
# manifests: …Extra site-served demo bundles (packages/<name>.json)
# gallery: featuredPin to the top (badge)
# gallery: skipOmit from the card grid
# gallery: binariesOmit (needs non-mip assets)

Hinch GUI smokes (nano_gui_simpletest, micro_gui_simpletest, touch_gui_simpletest) rely on fetch_ph_gui from the matching setup module — no gallery package header. First open needs network; later loads in the same session reuse the VFS until reload.

Featured starters: pydevices_demo, testris. See scripts/gallery_generator.py and examples catalog.

Board config

board_configs/psdisplay/ — 320×480 canvas with neutral host input exported to the coordinator selected by the application.

Headless / CDP troubleshooting

Prefer Playwright helpers over poking the IDE browser when demos hang:

ScriptPurpose
tools/ps_debug.pyCDP console + network probe for a harness/load URL
tools/ps_shot.pyTimed screenshot with a hard kill if Chromium stalls
python tools/serve.py   # separate terminal
.venv/bin/python tools/ps_debug.py \
  'http://127.0.0.1:8000/.site/pyscript/harness.html?modules=calc_graphics,calc_engine&autotest=1' 20

Common wedge: sync multimer.sleep_ms (or other blocking sleep) on the main thread often stalls page.evaluate and screenshots — the browser never yields. Prefer runtime.run_forever() / async sleep patterns from the asyncio guide. Capture console/CDP output with ps_debug.py before assuming a gallery or package map regression.

Matrix notes (serve.py, Playwright install, needs_playwright): tools/README.md — Example test matrix.

Next

Reference