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

Toplevel and Dynlink

This page explains how to build an OCaml toplevel (REPL) that runs in the browser, and how to use dynamic linking to load bytecode at runtime.

Building a toplevel

A toplevel is an interactive OCaml environment (like ocaml or utop). Js_of_ocaml can compile a toplevel to JavaScript, allowing it to run in the browser. See the live demo.

Steps

  1. Initialize the toplevel in your OCaml code using Js_of_ocaml_toplevel.JsooTop.initialize
  1. Build your bytecode with debug info and linkall:
ocamlfind ocamlc -g -linkall -package js_of_ocaml-toplevel \
    -linkpkg toplevel.ml -o toplevel.byte
  1. Compile to JavaScript with the --toplevel flag:
js_of_ocaml --toplevel toplevel.byte -o toplevel.js

Limiting available modules

By default, all linked modules are available in the toplevel. To limit this, use --export FILE where FILE lists compilation unit names (one per line).

The jsoo_listunits tool generates this list from findlib libraries:

jsoo_listunits -o units.txt stdlib str
js_of_ocaml --toplevel --export units.txt toplevel.byte

OCaml's Dynlink module lets you load bytecode files at runtime. This works in js_of_ocaml with some setup.

Steps

  1. Link js_of_ocaml-compiler.dynlink in your program (initializes dynlink support)
  1. Build your bytecode with debug info and linkall:
ocamlfind ocamlc -g -linkall -package dynlink \
    -package js_of_ocaml-compiler.dynlink -linkpkg main.ml -o main.byte
  1. Compile to JavaScript with the --dynlink flag:
js_of_ocaml --dynlink main.byte -o main.js

Example

(* main.ml *)
let () = Dynlink.loadfile "./plugin.cmo"
# Compile main program
ocamlfind ocamlc -g -linkall -package dynlink \
    -package js_of_ocaml-compiler.dynlink -linkpkg main.ml -o main.byte
js_of_ocaml --dynlink main.byte -o main.js

# Compile plugin
ocamlfind ocamlc -c plugin.ml

# Run
node ./main.js

See also