Warning: Reason support is experimental. We are looking for beta-tester and contributors.

Wasm_of_ocaml

Overview

Wasm_of_ocaml is a compiler from OCaml bytecode programs to WebAssembly. It provides an alternative way to run pure OCaml programs in JavaScript environments like browsers and Node.js.

The compiler is provided by the wasm_of_ocaml-compiler package. The Js_of_ocaml libraries are compatible with this compiler.

Installation

The easiest way to install wasm_of_ocaml is to use opam:

opam install wasm_of_ocaml-compiler js_of_ocaml js_of_ocaml-ppx js_of_ocaml-lwt

Binaryen version 119 or later is required. The opam command above will install it automatically if needed.

Usage

Your program must first be compiled using the OCaml bytecode compiler ocamlc. JavaScript bindings are provided by the js_of_ocaml package and the syntax extension by the js_of_ocaml-ppx package:

ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-ppx \
    -linkpkg -o cubes.byte cubes.ml

Then, run the wasm_of_ocaml compiler to produce Wasm code:

wasm_of_ocaml cubes.byte

This produces a JavaScript loading script cubes.js and a directory cubes.assets containing the Wasm code.

With dune

Dune has native support for wasm_of_ocaml (starting with dune 3.17.0). It supports both standard and separate compilation. See https://dune.readthedocs.io/en/latest/wasmoo.html

Supported features

Most of the OCaml standard library is supported. However:

  • Most of the Sys module is not supported

Extra libraries distributed with OCaml (such as Thread) are not supported in general. However:

  • Bigarray - supported using Typed Arrays
  • Str - supported
  • Graphics - partially supported using canvas (see also js_of_ocaml-lwt.graphics)
  • Unix - time-related functions are supported

Differences from js_of_ocaml

Compared to js_of_ocaml:

  • Dynlink is not supported
  • Building an OCaml toplevel is not possible
  • The virtual filesystem is not implemented

Effect handlers

OCaml 5.x code using effect handlers can be compiled in two ways:

The CPS transformation is not the default since the generated code is slower, larger, and less readable. However, the JSPI extension is not yet enabled by default in web browsers, and performing effects is slower when using it.

Binding with JavaScript libraries

Js_of_ocaml lets you bind code with JavaScript libraries by linking .js files. Similarly, wasm_of_ocaml allows linking Wasm modules (.wasm or .wat files). See Writing Wasm primitives.

If a js_of_ocaml project uses external primitives defined in companion .js files, you need to implement the same primitives in Wasm modules to build with wasm_of_ocaml.

See also