OCaml 5 · Eio · effects, not callbacks

Build web applications in OCaml

araara is a web framework for OCaml 5. It gives you what a real web application needs — logins and sessions, a database layer, type-safe HTML, real-time updates, and background jobs, with clustering when you grow into it — and a clear, consistent way to wire them together.

Get startedRead the docs

examples/hcs_hello/main.ml — builds from this site's repo
(* The smallest araara service: one route, one typed view, one server.
   Run with: dune exec examples/hcs_hello/main.exe *)

let hello_page =
  let open Tyxml.Html in
  html
    (head (title (txt "Hello from araara")) [])
    (body [ h1 [ txt "Hello, araara!" ] ])

let hello _params _req =
  Hcs.Server.respond_html (Format.asprintf "%a" (Tyxml.Html.pp ()) hello_page)

let () =
  Eio_main.run @@ fun env ->
  Eio.Switch.run @@ fun sw ->
  let routes =
    Hcs.Router.(compile_scopes [ scope "/" [ Route.get "/" hello ] ])
  in
  let handler =
    Hcs.Endpoint.(
      create default_config |> Fun.flip router routes |> to_handler)
  in
  Hcs.Server.run ~sw
    ~net:(Eio.Stdenv.net env)
    ~clock:(Eio.Stdenv.clock env)
    handler

Features

Everything you need to build a web application

Each of these is something a real application needs sooner or later. araara gives you all of them, built to work together — not a pile of libraries you have to integrate yourself.

Authentication & sessions

Sessions, CSRF protection, login flows, API tokens and rate limiting all slot into your request pipeline as composable steps. You can see exactly how every route is protected in one place, instead of hunting through handlers.

SQL for Postgres, SQLite & MySQL

Typed schemas, input that's checked before it ever reaches the database, and a query builder you compose in OCaml rather than writing raw SQL. Define your models once and run them against all three databases, through repodb.

Type-safe HTML

Render pages as ordinary OCaml functions — escaped by default, htmx attributes built in, no template language and no build step between you and the browser.

Real-time sync, server to client

Share a live document between the server and the browser. JSON CRDTs merge edits made in different places at once, with no conflicts, and they use the same wire format as json-joy — so your OCaml backend and a JavaScript client stay perfectly in sync.

Background jobs, workers & clusters

Move slow work off the request path into supervised background workers, with typed mailboxes, schedulers and one-off tasks. And when a single machine isn't enough, the same worker code spreads across a cluster of them.

HTML over the wire

Update the page by swapping in server-rendered HTML with htmx, and push live changes over Server-Sent Events. When you genuinely need a JSON API, every web action already has a matching endpoint built on the same logic.

Fast JSON APIs

Decode request bodies into typed OCaml values and encode responses at SIMD speed — with a zero-copy path for the endpoints that need every microsecond.

One binary, one container

Server, migrations, CLI and background workers compile to a single native binary. Ship it as one small Docker image — like this very site — or wrap it as a desktop app.

Performance

How fast is it?

araara's HTTP layer, hcs, is built for speed. We run it head-to-head with Go, Rust and PHP servers — same machine, same load — and it leads on WebSocket echo, HTTP/2 and static files while keeping pace on the rest. These are narrow, synthetic tests, though: they compare servers fairly, but they can't tell you how your own application will perform under real traffic. The full numbers are on the table, caveats and all.

See the benchmarks

Conventions

One shape for every feature

Every feature follows the same path through the same layers — model, context, controller or API, view, router — so once you've found your way around one araara codebase, you know your way around all of them. The conventions lean on OCaml's type system to stop whole classes of mistakes from ever compiling.

Read the conventions

See it running

Real applications, built with araara

Brote market simulator

A clustered trading-floor demo: two visible browser clients connect to different nodes while one thousand simulated traders place buy and sell orders, post chat messages, and drive realtime dashboard, portfolio and leaderboard updates over one multiplexed WebSocket per client. The trading book and chat log converge across the cluster with hive replicated state.

Read the source1000 simulated traders

Helpdesk realtime

A complete araara application from the docs: login, roles, typed routes, SQLite models, server-rendered HTML, htmx form updates and an operator queue that receives new tickets over Server-Sent Events.

Read the walkthroughSSE + htmx

ahoj — connect your email

ahoj

A complete email client: a curated inbox, a screener for unknown senders, full-text search, and a JSON API behind the same service layer as the HTML UI — shipped as web, CLI and desktop from one OCaml codebase.

Read the sourcedocker pull qswarm/ahoj:latest

a multiplayer snake game running on a hive cluster

Snake on hive

A multiplayer snake game on a hive cluster: every node runs identical code, simulates the snakes joined through it, and competes for singleton roles — the food spawner and the AI seats — that live on one node and migrate with membership.

Read the source

Thank you

Built on the shoulders of the OCaml community

araara is a small thing standing on a large foundation. The features above are possible only because of the libraries, knowledge and know-how the OCaml community has written and given away.

Everyone we build on