Skip to main content

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.

Not a stable embeddable API

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-pack and wasm-opt (wasm-opt must be on PATH; 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 on PATH (llvm-config --version should 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:

MethodRole
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.