= Wasm_of_ocaml

==@@id="overview"@@ 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 <<a_manual chapter="overview"|Js_of_ocaml libraries>> are compatible
with this compiler.

==@@id="installation"@@ 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.

==@@id="usage"@@ 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

==@@id="supported-features"@@ 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:

* **{{{--effects=cps}}}** - Uses the CPS transformation from js_of_ocaml
* **{{{--effects=jspi}}}** (default) - Uses the [[https://github.com/WebAssembly/js-promise-integration|JavaScript-Promise Integration extension]]

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.

==@@id="js-bindings"@@ 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 <<a_manual chapter="wasm_runtime"|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

* <<a_manual chapter="wasm_runtime"|Writing Wasm primitives>> — Implement custom Wasm primitives
* <<a_manual chapter="overview"|Js_of_ocaml overview>> — JavaScript compilation alternative
