Wasm Compilation With Wasm_of_ocaml

Wasm_of_ocaml is a compiler from OCaml to WebAssembly (Wasm for short). The compiler works by translating OCaml bytecode to Wasm code. The compiler can currently be installed from [its Github repository](https://github.com/ocaml-wasm/wasm_of_ocaml).

Compiling to Wasm

Dune has full support for building wasm_of_ocaml libraries and executables transparently. There’s no need to customise or enable anything to compile OCaml libraries/executables to Wasm.

To build a Wasm executable, just define an executable as you would normally. Consider this example:

$ echo 'print_endline "hello from wasm"' > foo.ml

With the following dune file:

(executable (name foo) (modes wasm))

And then request the .wasm.js target:

$ dune build ./foo.bc.wasm.js
$ node _build/default/foo.bc.wasm.js
hello from wasm

If you’re using the js_of_ocaml syntax extension, you must remember to add the appropriate PPX in the preprocess field:

(executable
 (name foo)
 (modes wasm)
 (preprocess (pps js_of_ocaml-ppx)))

Selective Compilation

The js and wasm modes can be selectively disabled using the (js_of_ocaml (enabled_if ...)) and (wasm_of_ocaml (enabled_if ...)) options. This allows for instance to generate one, or the other dependings on a profile:

(env
 (js-only
  (wasm_of_ocaml
   (enabled_if false)))
 (wasm-only
  (js_of_ocaml
   (enabled_if false))))

To be able to invoke the generated code using the same JavaScript script name in all cases, you can add a rule to copy the Wasm launcher script when the js_of_ocaml compilation is disabled.

(rule
 (action
  (copy foo.bc.wasm.js foo.bc.js))
 (enabled_if
  (= %{profile} wasm-only)))

Separate Compilation

Dune supports two modes of compilation:

  • Direct compilation of a bytecode program to Wasm. This mode allows wasm_of_ocaml to perform whole-program deadcode elimination and whole-program inlining.

  • Separate compilation, where compilation units are compiled to Wasm separately and then linked together. This mode is useful during development as it builds more quickly.

The separate compilation mode will be selected when the build profile is dev, which is the default. It can also be explicitly specified in an env stanza (see env) or per executable inside (wasm_of_ocaml (compilation_mode ...)) (see executable)

Sourcemap

Wasm_of_ocaml can generate sourcemaps for the generated Wasm code. By default, they are generated when using the dev build profile and are not generated otherwise. The behavior can explicitly be specified in an env stanza (see env) or per executable inside (wasm_of_ocaml (sourcemap ...)) (see executable)