Installation

pip install textual-wasm

That is enough for doctor, build and dev — the three commands most people need. It brings Textual, Rich and a small pure-Python closure with it, and nothing that has to be compiled.

Note

To track unreleased work, install from the repository instead:

pip install git+https://github.com/KaiErikNiermann/textual-wasm

Python version

3.12 or newer on your development machine. Note this is separate from the interpreter your app runs on in a browser, which is whatever CPython the pinned Pyodide ships — 3.14 at present. textual-wasm check reports both, and a difference between them is expected:

platform          linux        emscripten
python_version    3.14.7       3.14.2
event_loop        _UnixSelector…  WebLoop

Optional tools

Nothing below is needed to build or serve a site. Each enables one leg of textual-wasm check, and a leg that cannot run is reported as skipped with the command that would enable it — never as a failure.

Tool

Unlocks

tmux

The real-terminal reference: your app on a real pty through Textual’s own driver, which is what the browser render is judged against.

Node + pyodide

The WASM leg: the same probe under Pyodide, headless and CI-able.

Node + playwright

The browser leg: a real build, served by a real dev server, rendered by a real browser engine.

Pick your platform and take the whole block, or the lines for the legs you want:

apt install tmux                                      # real-terminal reference
pnpm add -D pyodide                                   # WASM leg
pnpm add -D playwright                                # browser leg
pnpm exec playwright install chromium firefox webkit  # browser leg: the engines
pacman -S tmux                                        # real-terminal reference
pnpm add -D pyodide                                   # WASM leg
pnpm add -D playwright                                # browser leg
pnpm exec playwright install chromium firefox webkit  # browser leg: the engines
brew install tmux                                     # real-terminal reference
pnpm add -D pyodide                                   # WASM leg
pnpm add -D playwright                                # browser leg
pnpm exec playwright install chromium firefox webkit  # browser leg: the engines

The npm packages are resolved by walking up from your working directory the way Node itself would, so a single node_modules at the root of a monorepo serves every project in it.

Playwright’s engines are downloaded separately from the package, which is why there are two commands. --browser chrome and --browser msedge drive the browsers already installed on your machine instead, and need no download at all — see Browser support.

For working on textual-wasm itself

git clone https://github.com/KaiErikNiermann/textual-wasm
cd textual-wasm
poetry install
pnpm install                       # only for the wasm and browser legs
git config core.hooksPath .githooks
poetry run pytest

The pre-push hook runs ruff, pyright in strict mode, radon, semgrep and the test suite. CI runs the same gates on the floor and ceiling of the supported Python range, plus the full four-runtime check with --strict.