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
- Initialize the toplevel in your OCaml code using Js_of_ocaml_toplevel.JsooTop.initialize
- Build your bytecode with debug info and linkall:
ocamlfind ocamlc -g -linkall -package js_of_ocaml-toplevel \
-linkpkg toplevel.ml -o toplevel.byte
- 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
Using the Dynlink library ¶
OCaml's Dynlink module lets you load bytecode files at runtime. This works in js_of_ocaml with some setup.
Steps
- Link js_of_ocaml-compiler.dynlink in your program (initializes dynlink support)
- 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
- 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
- Command-line options — The --toplevel and --dynlink flags
- Compilation modes — Whole program vs separate compilation
- Api introduction — Toplevel API