stable-haskell wasm
Install a Haskell-to-WebAssembly cross-compiler in two ghcup commands
and ship a wasm binary in three.
Quick install
ghcup config add-release-channel \
https://stable-haskell.github.io/ghc/ghcup-wasm.yaml
ghcup install ghc wasm32-wasi-9.14.0.stable.12
ghcup install cabal 3.17.0.0.stable.0
ghcup set cabal 3.17.0.0.stable.0
You also need Node.js 22+ on $PATH — both post-link and the runtime use
it. Non-TH compiles work without it; the compiler emits a clear actionable
error when TH needs it.
Why Node 22?
post-link.mjs (the JSFFI glue generator that ships with the cross-compiler)
uses import.meta.filename, which was added in Node 20.11. On older
nodes (e.g. Ubuntu noble's apt nodejs 18.x) it silently exits without
writing the glue, breaking JSFFI runs at instantiation time.
What's in this channel
| Tool | Version |
|---|---|
| GHC (wasm32-unknown-wasi) | wasm32-wasi-9.14.0.stable.12 |
cabal-install (dual-compiler) |
3.17.0.0.stable.0 |
The cabal-install here ships a target-prefix-aware
guessGhcPkgFromGhcPath
patch so one cabal build invocation can drive two GHCs — a native one
for Setup.hs and Template Haskell host execution, and the wasm
cross-compiler for the package code itself.
Host platforms
| Host | Status |
|---|---|
aarch64-darwin (Apple Silicon) |
✅ shipping |
x86_64-linux |
✅ shipping |
aarch64-linux |
✅ shipping |
x86_64-darwin, Windows |
follow-up |
Next steps
- Install — the full install path with troubleshooting links
- hello template — 90 seconds to a working wasm reactor
- miso-counter template — full interactive UI with 50+ TH-heavy deps
- Anatomy — what each file in the template actually does
- Troubleshooting — common errors and fixes