Design decisions of jsoo vs caramel

Can anyone offer insights on:

  1. what are the differences in the vs jsoo transpilers ?

  2. how is #1 influenced by the erlang vs js runtimess

  3. is one of the most stable ways to do “fault tolerant” programming in OCaml ?

Thanks! (Background: mostly familiar with JS runtime; not familiar with the Erlang / beam runtime; tried dialyzer [success typer of Erlang], but never got it working well)

As far as I know Caramel was a highly experimental port of OCaml to the BEAM runtime by one guy, who has since moved on to other things. It’s not something anyone should deploy to production.


Just to add a citation for @yawaramin’s tl;dr, @ostera talked about his plans re: Caramel in a discord message:

Caramel has been inactive for quite a bit since the last rewrite – I’ve got no plans of reviving it any time soon.

The “other things” seems to be Warp, a new build system.


Hi @zeroexcuses, Caramel author here.

Jsoo works off the bytecode, while Caramel compiles OCaml Lambda to Core Erlang.

Can’t speak for Jsoo, but I chose to compile to Core Erlang instead of writing a bytecode interpreter because it would get us closer to BEAM ecosystem. In that sense, Caramel is closer to Reason or ReScript than it is to Jsoo.

Like @yawaramin said, Caramel is not production ready. And as @cemerick said, I’m not planning on working on it any time soon.

Now with that disclaimer…I still think that the philosophy of Erlang of “let it crash” is a great platform for the OCaml language. Maybe less interesting with the advent of multicore, but even then a good resource for understanding how to build reliable systems beyond the type-system guarantees.

You can read more about this here:


Hi @ostera ,

thank you for your detailed and informative response.

I have an offtopic but related question – do you do any fault tolerant programming these days? If so, what do you use ?

I haven’t tried it out yet, but you might find this interesting:

Definitely interesting. I have also been thinking about

ML → rescript (smaller output than jsoo) → JS → run on V8 isolates; i.e. each V8 isolate == job of a erlang process

In fact Cloudflare a while back published a demo: GitHub - cloudflare/reason-worker-hello-world: Reason hello world for Cloudflare Workers

1 Like

Primarily Elixir due to the larger ecosystem, but looking forward to writing Gleam. Really, the BEAM is the safest bet for making systems that need to run forever.

I also experimented using v8 isolates as processes but an isolate is a much larger thing than a BEAM process, and it shows when you start pushing it. Cloudflare claims that the v8 runtime can handle thousands of isolates. If memory serves me well, in the Erlang Programming book very early on they have you spin up ~3 million processes on your own computer.

Of course, you can build reliable software in other languages/platforms too, but you usually end up with an ad hoc, informally specified, bug-ridden, slow implementation of half of Erlang.


In my limited experience with Elixir/Erlang, it is hard to develop without a type system, and dialyzer doesn’t really cut it.

Have you toyed with compiling a SUBSET of OCaml rather than the entire bytecode? For example: throw out imperative OCaml, throw out ref, only have “mathematically pure” OCaml – this would in theory be a much closer to BEAM semantics.

The main benefit here is we still get the type system type checking of OCaml.

1 Like

My impression is that the prominent typed languages on BEAM is Gleam. It gives off a rust vibe but it’s otherwise ML-like.


This is exactly what Caramel was. Compiled from lamdba core without mutability and a bunch of other things that wouldn’t play well on the Erlang VM.

Anyone know if there is a port of to a typed language ? Currently the main thing I want an OCaml → beam compiler for.