| --- |
| title: WebAssembly |
| slug: /wasm |
| description: How Pyrefly's WebAssembly build is used, built, and what the current API covers |
| --- |
| |
| {/* |
| * Copyright (c) Meta Platforms, Inc. and affiliates. |
| * |
| * This source code is licensed under the MIT license found in the |
| * LICENSE file in the root directory of this source tree. |
| */} |
| |
| # 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](https://pyrefly.org/sandbox/) works. |
| |
| :::warning 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/`](https://github.com/facebook/pyrefly/tree/main/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](https://rustup.rs/) with `wasm32-unknown-unknown`. |
| - [`wasm-pack`](https://rustwasm.github.io/wasm-pack/installer/) and |
| [`wasm-opt`](https://github.com/WebAssembly/binaryen) (`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: |
| |
| ```bash |
| 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`](https://github.com/facebook/pyrefly/blob/main/website/README.md). |
| In short: |
| |
| ```bash |
| 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`](https://github.com/facebook/pyrefly/blob/main/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`](https://github.com/facebook/pyrefly/blob/main/website/src/sandbox/Sandbox.tsx) |
| 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`](https://github.com/facebook/pyrefly/blob/main/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](./configuration.mdx). |
| |
| ## Related source |
| |
| - [`pyrefly_wasm/README.md`](https://github.com/facebook/pyrefly/blob/main/pyrefly_wasm/README.md) — crate build notes |
| - [`website/README.md`](https://github.com/facebook/pyrefly/blob/main/website/README.md) — sandbox and docs site |
| - [Sandbox](/sandbox) |