Library / SDK
janestreet/bonsai avatar
janestreet/bonsai

Bonsai: incremental OCaml state machines

A library for building dynamic webapps, using Js_of_ocaml

1,420 stars58 forksOCamlMIT

At a glance

What is it?
Bonsai is an OCaml library for composing incremental, purely functional state machines. It is the generic core behind browser and terminal interfaces, while companion packages provide environment-specific UI behavior.
Who is it for?
Bonsai fits OCaml teams that want shared business logic, fine-grained incremental computation, and state managed outside the visual component hierarchy. It is less suitable for developers seeking a conventional component-first framework or a self-contained browser starter.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 105 days ago.
What is it written in?
Mainly OCaml, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Bonsai separates application state from browser rendering

Bonsai addresses the construction of reactive applications in OCaml, with particular value for systems that share domain logic between a browser and a server. Its users include teams building interactive web applications and terminal interfaces, especially organizations already invested in OCaml's type system. The repository describes Bonsai itself as a general-purpose library for incremental, composable state machines. Browser specialization belongs to the separate Bonsai_web project rather than to the generic core.

The central design choice is to separate state, incremental computation, and rendering. Many component-oriented frameworks combine those concerns in one UI abstraction. Bonsai instead lets developers compose state and incrementalization primitives independently. A computation can avoid running again until a relevant input changes, whether it produces interface data or handles business logic over a live-updating dataset. The README describes this as loosely comparable to React hooks, but with state managed outside the component hierarchy.

This architecture is relevant to directories, dashboards, and operational interfaces that react to changing data. The README states that Bonsai is used to build almost all web applications inside Jane Street, including a corporate directory and tools that interact with trading systems. This establishes substantial internal use, but it does not prove that the public library will fit every OCaml project. The surrounding application, its OCaml version, and its delivery system still need separate evaluation.

How Bonsai limits recomputation in its graph

A Bonsai component is documented as a purely functional state machine. A graph connects state, derived values, and event handlers, while incrementalization limits recomputation to affected values. The README says this applies to every value rather than just rendered output. That wider scope is the most important technical distinction in the project.

In the dice example, `Bonsai.state` receives an initial face and a graph, then returns the current value and a function that changes it. The HTML reads the current `face`, while the button's `on_click` handler passes a newly selected face to `set_face`. A click therefore updates the graph instead of directly mutating the DOM. Another graph branch can observe or derive from the same state without requiring it to be manually copied into a top-level component model.

The project treats lifecycle and scoping as consequences of keeping state independent of visual components. In a tabbed interface with several stateful regions, Bonsai manages state scope as users interact with those regions. The README says developers do not need to hoist every nested component's internal state into one application-level model. This is a meaningful distinction from component-owned state, but it also means adoption requires learning Bonsai's graph, lifecycle, and scoping abstractions rather than expecting them to remain invisible behind ordinary component syntax.

Building the Bonsai core with Dune

The repository provides a Makefile with standard Dune targets, but the README does not provide a package-manager installation command or a complete browser-project setup. For the core repository, the documented build operation is `dune build`. A successful invocation should finish without reporting a build failure.

bash
dune build

The installation operation exposed by the Makefile is `dune install`. It accepts the Makefile's optional prefix setting, but the repository does not document a project-specific destination.

bash
dune install

The Makefile also exposes removal and cleaning operations through `dune uninstall` and `dune clean`. Those are exact repository commands and are preferable to constructing an unspecified package installation instruction.

bash
dune clean

This is installation of the core library only. The README directs browser users to a separate Bonsai Web quick start and does not give a first-run development-server command here. The repository therefore does not support a complete claim such as “install Bonsai and launch a generated app” without consulting another project.

A first reactive Dice state machine

The README's first interactive example defines a small `Dice` component. The following excerpt is taken directly from that example and is incomplete because it stops before the complete HTML block:

ocaml
module Dice = struct
  let faces =
    [ "⚀"; "⚁"; "⚂"; "⚃"; "⚄"; "⚅" ]
  ;;

  let component (graph @ local) =
    (* Components are implemented as purely functional state machines. *)
    let face, set_face = Bonsai.state (List.hd_exn faces) graph in
    (* Components are incrementally rendered, only when the relevant parts of the state change. *)
    let%arr face and set_face in

`faces` contains six possible results. `Bonsai.state` creates the current `face` and its `set_face` updater within the supplied graph. The comments also identify the two intended properties: the component is a purely functional state machine, and only relevant parts of its state trigger rendering.

The rest of the README example binds `face` into a `{%html|...|}` block. Its button uses `Random.int` to select another value, then calls `set_face`. Activating the button updates the state, after which the affected view is rendered. The core repository does not show a command that compiles and launches this excerpt on its own, so a first browser run must follow the linked Bonsai Web setup.

Bonsai tests exercise virtual DOM transitions

Bonsai includes an expect-test facility for expressing interface behavior without manually clicking through an application. The README's user-selector example creates a `Handle`, displays its virtual DOM, calls `Handle.input_text`, and then requests a diff. The expected output changes from a greeting to the same greeting followed by the entered value.

This style records the interface at two points in one scenario. According to the README, the diff can show changes to HTML attributes, class names, and other rendered details. Tests may also include mock server calls and involve state changes that drive the interface. This matters for workflows where an event handler, server response, state transition, and view update form one behavioral sequence.

The repository presents whole-app automated testing as a supported capability, but it does not document every command or configuration needed to run Bonsai tests from a generated application. The example therefore demonstrates the testing model, not a complete test runner setup. A prospective user must find the applicable runner configuration in the application or companion documentation.

There is also a package boundary to keep clear. Bonsai supplies the incremental state-machine foundation, while Bonsai_web specializes it for browser interfaces. A feature visible in a web application does not automatically establish that every supporting package and runner lives in this repository.

Where Bonsai is the wrong tool

The clearest limitation is conceptual. Bonsai asks developers to reason about functional state machines, incremental dependencies, lifecycle, and scope. Teams that want a conventional component abstraction where rendering, local state, and updates are handled as one unit may find this separation unfamiliar. The README presents that difference as a deliberate architectural choice, not as a defect.

This repository is also not a complete browser distribution. The core library can be specialized by Bonsai_web for browsers or Bonsai_term for interactive terminal interfaces. The README does not document HTTP routing, production serving, browser bundling, deployment, rollback, or supported Js_of_ocaml versions for a newly created Bonsai application. Those omissions matter when assessing Bonsai as an all-in-one web framework rather than as its actual role, the underlying state-machine library.

Implementation introduces another requirement: developers need an OCaml toolchain and comfort with typed functional code. Repository entries include `ppx_bonsai`, while the primary language is OCaml. Bonsai can allow business logic and types to be shared between frontend and backend, but that benefit is most useful to teams already prepared to operate OCaml across both environments.

Bonsai core compared with its UI companions

The most direct architectural alternative shown in the repository is a different layer. Bonsai_web builds browser-oriented reactive interfaces on top of the generic Bonsai library, while Bonsai_term targets interactive terminal interfaces. Both use the core's incremental state-machine approach rather than duplicating application state in a separate visual model.

A React-style component library provides a useful conceptual contrast, although the README does not name a particular substitute to adopt. In Bonsai, state is not associated with explicit components in the same way, and incrementalization applies throughout the graph. Bonsai_web then supplies browser-oriented templating, component-specific stylesheets, and rendering behavior. Core Bonsai should be evaluated for its graph model; a web project must also evaluate Bonsai_web.

Maintenance information requires care. The repository is not archived, and its last push was on 2026-07-10. However, the only listed recent release is `v0.15.1`, dated 2022-10-14. Those facts do not establish current release cadence or version compatibility. Before selecting a release, an adopter should inspect `CHANGES.md`, `changelog.md`, `bonsai.opam`, and the dependency and release state of the intended companion project. The MIT license permits use and modification under its stated terms, but the exact `LICENSE.md` should be retained with the selected version.

Editorial conclusion

Bonsai fits OCaml teams that want shared business logic, fine-grained incremental computation, and state managed outside the visual component hierarchy. It is less suitable for developers seeking a conventional component-first framework or a self-contained browser starter. Before adoption, inspect the Bonsai Web quick start, confirm that Js_of_ocaml fits the deployment target, and review the current package versions because the latest listed Bonsai release is dated 2022-10-14.

Frequently asked questions

What is janestreet/bonsai used for?

Bonsai provides composable, incremental, purely functional state machines in OCaml. Its core is generic, while companion projects specialize it for browser and terminal interfaces.

Does janestreet/bonsai include a browser UI framework?

The README describes Bonsai as the generic core library. Browser-focused functionality is supplied by the separate Bonsai_web project.

How do I build and install janestreet/bonsai?

The core repository documents `dune build` for compilation and `dune install` for installation. It does not provide a complete browser-application launch command.

Can janestreet/bonsai test reactive interface behavior?

The README shows expect tests that manipulate interface elements and inspect virtual DOM differences. It also states that tests can include mock server calls and verify state that drives the interface.

Which license does janestreet/bonsai use?

The repository identifies Bonsai as licensed under the MIT License. The exact terms are recorded in `LICENSE.md`.

Official sources

  1. Issues
  2. janestreet/bonsai on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/janestreet-bonsai.svg)](https://hysenlabs.com/projects/janestreet-bonsai)

Was this useful?