blob: 72a029c15676564f74bfcedde4225ae728413340 [file] [edit]
---
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)