= Runtime files =

For compiling a bytecode executable to JavaScript, one often need to pass
JavaScript runtime files for some OCaml libraries used by the
executable. Tracking the required runtime files is done using the de-facto
standard for library management in OCaml, Findlib.


== Listing js runtime files

To list all JavaScript runtime files for a set of libraries:

{{{
  ocamlfind query -format "%+(jsoo_runtime)" -r LIB1 LIB2 ... | grep -v "^$"
}}}

For example, for **base** and **time_now**

{{{
  $ ocamlfind query -format "%+(jsoo_runtime)" -r base time_now | grep -v "^$"
  ~/.opam/4.14.0/lib/base/base_internalhash_types/runtime.js
  ~/.opam/4.14.0/lib/base/runtime.js
  ~/.opam/4.14.0/lib/time_now/runtime.js
}}}

Here is minimal example of manually compiling a single ml file program:
{{{
  $ export LIBS=base,time_now
  $ ocamlfind ocamlc -package $LIBS -linkpkg main.ml -o main.byte
  $ js_of_ocaml $(ocamlfind query -format "%+(jsoo_runtime)" -r $LIBS) main.byte
}}}

== Declaring runtime JavaScript files inside a META file

The **jsoo_runtime** variable is used to declare one or more runtime files.
Files must be coma-separated and should be plain names relative to the package directory.

For example, to declare that **mypackage.sublib** requires the file **mypackage/subdir/runtime.js**
{{{
  cat mypackage/META
  package "sublib" (
    directory = "subdir"
    jsoo_runtime = "runtime.js"
  )
}}}

While the mechanism allows arbitrary naming for the javascript files,
if there is only one file, we suggest naming it **runtime.js** by
convention.

== The old deprecated way

Before dune and its native support for js_of_ocaml, the (hacky) way
to rely on Findlib was to use a **linkopts** variable with a **javascript**
predicate {{{linkopts(javascript)}}} and have js_of_ocaml be responsible for
looking up the files in the right directory.

This approach is not very satisfying:
* It makes it harder for a build system to know the set of dependencies.
* The js_of_ocaml compiler needs to perform findlib resolution itself.

=== Listing linkopts

To list all {{{linkopts(javascript)}}} for a set of libraries:

{{{
  ocamlfind query -o-format -r -predicates javascript LIB1 LIB2 ...
}}}

For example, for **base** and **time_now**

{{{
  $ ocamlfind query -o-format -r -predicates javascript base time_now
  +base/base_internalhash_types/runtime.js
  +base/runtime.js
  +time_now/runtime.js
}}}

=== Declaring runtime JavaScript files inside META files

The content of {{{linkopts(javascript)}}} is given directly to the
js_of_ocaml compiler.  To be able reference files independently of the
installation path, we rely on js_of_ocaml's findlib support (see Command-Line findlib support below).

For example, to declare that **mypackage.sublib** requires the file **mypackage/subdir/runtime.js**

{{{
  cat mypackage/META
  package "sublib" (
    directory = "subdir"
    linkopts(javascript) = "+mypackage/sublib/runtime.js"
  )
}}}

== Command line findlib support (deprecated)
If js_of_ocaml is compiled with findlib support, one can use the
following syntax to reference JavaScript files:
* {{{ +{findlib-package}/{javascript-file} }}}
* {{{ +{javascript-file} }}}

The file **javascript-file** will be looked up inside the **findlib-package** lib directory.

When no package is provided, the compiler will look inside js_of_ocaml-compiler lib directory.

For example, if findlib install all libraries inside ${LIBDIR}:
* {{{+mypackage/jsfile.js}}} resolves to {{{${LIBDIR}/mypackage/jsfile.js}}}
* {{{+mypackage/dir/jsfile.js}}} resolves to {{{${LIBDIR}/mypackage/dir/jsfile.js}}}
* {{{+toplevel.js}}} resolves to {{{${LIBDIR}/js_of_ocaml-compiler/jsfile.js}}}

== Compatibility

**dune** generate META files that are usable with the old deprecated
way.  However, it only uses **jsoo_runtime** to look up information.

**js_of_ocaml-ocamlbuild** uses **jsoo_runtime** by default starting with version 5.0.