Two ways of interfacing JS lib / jsoo?

There appears to be (atleast) two ways of interfacing JS code with jsoo:

  1. GitHub - ml-in-barcelona/jsoo-react: js_of_ocaml bindings for ReactJS. Based on ReasonReact. // external bundling

  2. jsoo-code-mirror/dune at bd1d3c68a23655cd667986aef48c05a6514fd194 · patricoferris/jsoo-code-mirror · GitHub “internal bundling”

By “external bunding”, the jsoo code emits require’s which some external bundler (say webpck or esbuild) then uses.

By “internal bundling”, we generate some *.js file (say via bable / esbuild/ webpack), then pass it to js_of_ocaml

My questions:

  1. What’s going on here? What is the pro/con of each ?

  2. I currently have a slight preference for “external” bundling – how can I convert an “internal bundling” (say the codemirror) example above into “external bundlihng”


The rationale for #2 is as follows, I currently have a build process that is:

  1. run dune
  2. run esbuild on *.bc.js files (required by jsoo-react)

With “internal bundling”, my process becomes:

  1. run dine
    1.5 as part of “run dune”, we may have to run babel to bundle some *.js file
  2. run esbuild on *.bc.js files (required by jsoo-react)

I’d prefer a world where I only run one of esbuild/babel, only have one node_modules directory, and just one post-jsoo bundle step.


Ultimately the difference is whether or not the JS libraries are vendored or not. If you want to try out jsoo-code-mirror you can opam pin it and just use your normal OCaml workflow for building a jsoo project (i.e. no JS tools needed). For jsoo-react as you point out you will need to pull in the JS tools for getting react and then bundling things. @jchavarri outlined the key differences very nicely in this issue Should jsoo-react vendor react.js? · Issue #104 · ml-in-barcelona/jsoo-react · GitHub.

I’m not quite sure I follow why this step is necessary? In a basic code-mirror setup you shouldn’t need any external JS tools (e.g. see If you want to override some of the global values through a .js file does it have to be run separately from the final bundle step?

My understanding is that every time I modify includes.js, I need to run babel to regenerate bundle.js . I was thinking about the dev case where I’m simultaneoujsly modifying *.ml and includes.js , say when hacking on the boundary.

Hmmm, do you need to be modifying include.js in the code mirror library? The idea was it came along with some basics that you might want and then if you didn’t like this you could override them and rebundle (I think that should work) from your library with your own include.js like thing?

I’m hacking on things like:

  1. injecting codemirror-vim
  2. making codemirror behave like a REPL in other cases

I’m not 100% sure, but I suspect yes.

I think the point here we are in agreement is – every time I modify includes.js , I need to rebundle – this is what I meant to say in step “1.5”