Run Lean 4 in the browser via WebAssembly.
This project is mainly based on @cauli's work to compile Lean 4 to WASM: cauli/lean4, with a web playground reference from cauli/lean4-wasm-in-browser.
npm install lean4.jsimport { Lean4 } from 'lean4.js'
const lean = new Lean4()
await lean.init()
const result = await lean.run('#eval 2 + 2')
console.log(result.stdout) // "4"
console.log(result.exitCode) // 0
lean.dispose()WASM assets are loaded from cloudflare R2 automatically. No extra setup needed.
Note: Your page must be served with COOP/COEP headers for SharedArrayBuffer support. See COOP/COEP setup below.
- Reduced unnecessary
.oleanartifacts inlean-lib(for example, private artifacts such asolean.private), bringing thelean-libsize down to about 90+ MB and the full bundle to about 300+ MB. This is acceptable for now, and there is still room for further size optimization. - Published
lean4.jsto npm for easier integration and reuse. - Deployed a web playground so people can try it directly in the browser.
- Even running a minimal Lean file still takes close to 1 minute, which is hard to use in production today.
- We tried to support
--server/--workermode in the browser, but this attempt failed. If startup can be paid only once (instead of per run), the project would become much more practical.
| Option | Type | Default | Description |
|---|---|---|---|
basePath |
string |
cloudflare R2 | URL where WASM assets are served. Override for self-hosting |
onProgress |
(msg: string) => void |
— | Progress callback during init |
timeout |
number |
120000 |
Execution timeout in ms |
Downloads and caches the .olean library bundle. Must be called before run(). Uses IndexedDB to cache for subsequent visits.
Runs Lean 4 code in an isolated iframe.
| Option | Type | Default | Description |
|---|---|---|---|
flags |
string[] |
['--json'] |
Lean CLI flags |
Returns { stdout: string, stderr: string, exitCode: number }.
Cleans up resources.
SharedArrayBuffer requires these server headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
import { lean4Plugin } from 'lean4.js/vite'
export default defineConfig({
plugins: [lean4Plugin()],
})Add headers in your server/hosting config (Nginx, Vercel, Netlify, etc.).
If you prefer not to use the CDN:
npx lean4-wasm-copy public/lean4-wasmconst lean = new Lean4({ basePath: '/lean4-wasm' })MIT