WebAssembly
Pyrefly can compile to WebAssembly so a browser can run the type checker and a
subset of language-server features without a native pyrefly binary. That is
how the Pyrefly sandbox works.
The WASM crate primarily powers the sandbox. Maintainers have not settled a
complete, backwards-compatible API for embedding Pyrefly in other web apps.
Method names and payloads can change. Test changes made for the sandbox in the
sandbox itself; treat pyrefly_wasm as an internal interface if you build from
source.
Build from source
The crate lives in
pyrefly_wasm/.
The website wires it into the sandbox under website/src/sandbox/.
Prerequisites
- Linux or macOS (website WASM workflows are not supported on native Windows; use WSL).
- Rust with
wasm32-unknown-unknown. wasm-packandwasm-opt(wasm-optmust be onPATH;wasm-pack’s bundled optimizer is disabled because it is outdated).- Clang / LLVM. On macOS:
brew install llvm. On Fedora/CentOS:sudo dnf install clang. If zstd fails to compile on a Mac, put Homebrew LLVM first onPATH(llvm-config --versionshould resolve). - Node.js and Yarn, if you will run the website.
Build the crate
From the repository root:
cd pyrefly_wasm
./build.sh
That runs wasm-pack for the web target and then wasm-opt -Os. Pass
--BUILD_FOR_TEST to target nodejs (used by website Jest tests).
Output lands in pyrefly_wasm/target/ (pyrefly_wasm.js and
pyrefly_wasm_bg.wasm). Copy those into the sandbox (or test) paths the
website README describes when you need a local rebuild.
Test changes in the sandbox
See website/README.md.
In short:
cd website
yarn install-with-wasm-deps # first time: build WASM + yarn install
yarn start-with-wasm # rebuild WASM and start Docusaurus
yarn start / yarn install only work on the static docs and do not rebuild
WASM. The sandbox is the primary consumer of pyrefly_wasm, so exercise the
affected sandbox behavior after changing its implementation or API.
Current API
pyrefly_wasm exports a State class (new State(version)) wrapping the
in-tree playground. The exports in
pyrefly_wasm/lib.rs
are the authoritative API reference. The current JavaScript names are:
| Method | Role |
|---|---|
updateSandboxFiles(files, forceUpdate) | Replace the virtual project (Record<string, string> of path → source). Returns an optional error string. |
updateSingleFile(filename, content) | Update one file. |
setActiveFile(filename) | Choose which file later queries apply to. |
getErrors() | Type errors for the project. |
hover(line, column) | Hover payload at a 0-based position, or null. |
gotoDefinition(line, column) | Definition ranges, or null. |
autoComplete(line, column) | Completions. |
inlayHint(callArgumentNames) | Inlay hints. |
semanticTokens(range) | Semantic tokens for an optional range. |
semanticTokensLegend() | Token types/modifiers legend. |
Positions match the playground (line / column as i32). Payloads are
serde-serialized into JS; there is no TypeScript .d.ts from wasm-pack
(--no-typescript). The sandbox keeps a local
PyreflyState
interface.
Some native features are compiled out with
#[cfg(not(target_arch = "wasm32"))]. If a WASM build fails with could not find … in the crate root, that crate is likely excluded from the WASM
target. See pyrefly_wasm/README.md.
Configuration
Sandbox files are an in-memory project, not your disk workspace. There is no
separate “WASM config” documented beyond what the playground/State accepts
when creating the instance (version is the Python version string passed to
State). For CLI and IDE configuration, use the
configuration reference.
Related source
pyrefly_wasm/README.md— crate build noteswebsite/README.md— sandbox and docs site- Sandbox