# 14. Using the GHC WebAssembly backend¶

## 14.1. What does the WebAssembly “backend” mean¶

In order to compile Haskell to wasm, you need a custom GHC build that targets wasm. There isn’t a GHC option which allows you to use a stock GHC installed via ghcup or stack to generate wasm. That’s because GHC is still a single-target compiler, so each GHC build is only capable of compiling code that runs on a single architecture and operating system.

So, the term GHC wasm backend isn’t the same sense as the unregisterised/LLVM/NCG backends. It merely describes GHC’s support as a cross compiler that targets wasm, and more specifically, wasm32-wasi.

The generated wasm module makes use of a few post-MVP extensions that are supported by default in latest releases of Chrome/Firefox/Safari/wasmtime. The wasm module uses WASI as the system call layer, so it’s supported by any wasm engine that implements WASI (including browsers, which can provide the WASI layer via JavaScript).

## 14.2. Setting up the GHC wasm backend¶

The wasm backend is still a tech preview and not included in the official bindists yet. If you are using x86_64-linux, you can follow the “getting started” subsections in ghc-wasm-meta to quickly set up the GHC wasm backend using the nightly artifacts.

It’s also possible to build the GHC wasm backend manually, if your host system is one of {x86_64,aarch64}-{linux,darwin}. Refer to the ghc-wasm-meta readme for detailed instructions.

## 14.4. Running the GHC wasm backend’s output¶

Once you have a wasm module, you can run it with a dedicated wasm engine like wasmtime, or inside the browsers.

To run it with wasmtime, you can simply do:

$wasmtime run foo.wasm  Just like native executables, you can pass command line arguments, and also RTS options, as long as it’s built with -rtsopts: $ wasmtime run foo.wasm --bar +RTS --nonmoving-gc -RTS


You can also mount some host directory into it:

$wasmtime run --mapdir /::$PWD foo.wasm


As long as the filesystem capability is provided, in addition to filesystem I/O in Haskell code, you can use the RTS eventlog and profiling functionality, then inspect the report files:

$wasmtime run --mapdir /::$PWD foo.wasm +RTS -hc -l -RTS


To run the wasm module in the browsers, refer to the ghc-wasm-meta documentation for more details.