caramel massively scalable,
zero runtime errors,
choose two.

Industrial-strength Safety

Caramel has a highly expressive, sound type-system, and a blazing fast type-checker. This allows you to rule out entire classes of errors by using types that are closer to your domain, and fearlessly refactor large amounts of code without sacrificing development speed.

To achieve this, Caramel is actually a backend to the OCaml compiler, so it reuses its entire type-checking stack, with well over 25 years and millions of hours of academic research and industrial usage, and provides a new compilation target to Erlang.

Don't let the candy fool you: this is not a toy.

Write Once, Run Forever

Caramel runs on the Erlang virtual machine, which is perhaps the most mature and reliable functional language runtime in the world. It has built-in error handling mechanisms that make it ideal for building systems that should never stop running, that need to handle massive concurrency in soft-real time, and that need to be built by just a handful of engineers.

This is the magic ingredient in companies like Whatsapp, Ericsson, Heroku, Klarna, and Discord, that build and operate their massively scalable systems with unbelievably small teams.

Open Source & Friendly

Caramel is built on Github, and we encourage contributions with the labels: good first issue and help wanted.

We aim to build a friendly community where people of any gender, background, and experience level can feel welcomed and are respected. To ensure this, we subscribe to a code of conduct.


Hello, Joe!
let hello = fun () -> Io.format "~p" ["Hello, Joe!"]
Basic HTTP Server
let handle conn =
  Gen_tcp.send conn "hello world";
  Gen_tcp.close conn

(* this function will actually new processes per connection, so we
   can easily handle millions of concurrent connections *)
let rec loop socket =
  let Ok conn = Gen_tcp.accept socket in
  let handler = Process.make (fun _self _recv -> handle conn ) in
  Gen_tcp.controlling_process conn handler;
  loop socket

let start port = Process.make (fun _self _recv ->
  let Ok socket = Gen_tcp.listen port [Active false; Packet Http] in
  loop socket)

Is it ready yet?

Not just yet, but you are welcome to take it for a spin in the releases page.

There is still plenty of work to do in getting the right libraries in place, but thankfully we are already over the biggest hump.

If you want to stay up to the date with the development, follow @leostera