Export OCaml code to JavaScript
This page explains how to make OCaml values (functions, objects, constants) accessible from JavaScript code.
Basic export with Js.export ¶
Use Js.export to export a single named value:
open Js_of_ocaml
let () =
Js.export "myMathLib"
(object%js
method add x y = x + y
method abs x = abs x
val zero = 0
end)From JavaScript:
myMathLib.add(3, 4); // 7
myMathLib.abs(-5); // 5
myMathLib.zero; // 0Exporting multiple values with Js.export_all ¶
Use Js.export_all to export all properties of an object as top-level exports:
let () =
Js.export_all
(object%js
method add x y = x + y
method sub x y = x - y
val version = Js.string "1.0.0"
end)From JavaScript:
add(3, 4); // 7 (directly accessible)
sub(5, 2); // 3
version; // "1.0.0"Exporting individual functions ¶
You can export plain OCaml functions. They are automatically wrapped for JavaScript:
let greet name =
"Hello, " ^ name ^ "!"
let factorial n =
let rec aux acc = function
| 0 -> acc
| n -> aux (acc * n) (n - 1)
in aux 1 n
let () =
Js.export "greet" greet;
Js.export "factorial" factorialFrom JavaScript:
greet("World"); // "Hello, World!"
factorial(5); // 120Type considerations ¶
Exported functions are automatically wrapped with Js.wrap_callback. However, you must convert OCaml values to their JavaScript equivalents (strings with Js.string, booleans with Js.bool, etc.). See type conversions for the full list.
Handling callbacks from JavaScript ¶
When JavaScript passes a callback to your OCaml code, you receive a JavaScript function. Use Js.Unsafe.fun_call to invoke it:
let () =
Js.export "utils"
(object%js
method forEach arr callback =
let len = arr##.length in
for i = 0 to len - 1 do
let item = Js.array_get arr i in
Js.Optdef.iter item (fun v ->
ignore (Js.Unsafe.fun_call callback [| Js.Unsafe.inject v |]))
done
end)From JavaScript:
utils.forEach([1, 2, 3], function(x) { console.log(x); });Using with Node.js ¶
Js.export and Js.export_all automatically use module.exports when running in Node.js:
(* math.ml *)
open Js_of_ocaml
let () =
Js.export_all
(object%js
method add x y = x + y
method mul x y = x * y
end)Build and use:
$ ocamlfind ocamlc -package js_of_ocaml,js_of_ocaml-ppx \
-linkpkg math.ml -o math.byte
$ js_of_ocaml math.byte -o math.js
$ node
> var math = require("./math.js");
> math.add(2, 3)
5
> math.mul(4, 5)
20
Using in browsers ¶
In browsers, exports are added to the global object (window):
<script src="math.js"></script>
<script>
console.log(myMathLib.add(2, 3));
</script>To avoid polluting the global namespace, you can export a single namespace object:
let () =
Js.export "MyApp"
(object%js
val math = object%js
method add x y = x + y
end
val utils = object%js
method log msg = Console.console##log msg
end
end)