This guide will teach you how
to build user interfaces in the
browser using several libraries,
primarily Bonsai
and Virtual_dom
.
Together, these libraries will
allow you to build applications
in a pure functional style
without needing to be exposed to
the impure, stateful API that
browsers provide.
In this guide we aim to explain how to use Bonsai, and to a certain degree, how Bonsai works under the hood. We hope that the latter will equip you with the necessary knowledge to tune the performance of your applications.
The browser understands three languages: Javascript, HTML, CSS. Jane Street programmers are mainly familiar with: OCaml. Thus, we’ve made it possible to write all three of the browser languages using OCaml.
js_of_ocaml
is
an OCaml-to-Javascript
compiler.virtual_dom
is
a library for building values
that represent a chunk of
HTML.css_gen
is a
library for writing CSS-styles
in a type safe manner.The CSS situation is a little
more nuanced, since we actually
recommend writing CSS directly
using ppx_css
.
A user interface is a function from data to view. In types:
(* Virtual_dom.Vdom.Node.t represents your applications view *)
open Virtual_dom
val ui : Your_input_type_here.t -> Vdom.Node.t
It’s easy to write composable views with such functions, since all you need to return is a plain old OCaml value. A small amount of boilerplate can turn this function into a simple web app that continuously displays the result of the function.
Of course, this is a huge simplification; in a real app, you usually want:
Bonsai provides these features while still encouraging the composition and abstraction properties of regular OCaml code. Bonsai wants you to forget it is there. The signature of a Bonsai app looks a bit like this:
open Bonsai_web
val ui : Your_input_type_here.t Value.t -> Vdom.Node.t Computation.t
It’s just like before, except
the input is wrapped with
Value.t
and the
output is wrapped with
Computation.t
.
While there is slightly more
friction, writing re-usable UI
components is just as easy. In
addition, we’ve expanded the
kinds of components you can
write, since
Computation.t
encapsulates incremental state
machines, which is how
interactivity is added to a
page.
Both these types are covered in detail in chapters 2 and 3.
The incrementality in Bonsai
comes from the
Incremental
library. When a web page loads,
Bonsai compiles the top-level
Vdom.Node.t Computation.t
into something akin to
Vdom.Node.t Incr.t
.
Then the Incr_dom
library handles running the main
loop to keep the incremental
graph stabilized
(i.e. up-to-date).
The Vdom.Node.t
representing the current view
gets put onto the screen via a
diff-and-patch process. The
virtual_dom
library
always keeps track of the
previous
Vdom.Node.t
that it
told the browser to display.
Whenever we request a
new
Vdom.Node.t
to be
displayed on the screen, the
library first compares it to the
previous view to see what
changed, and then it applies
just those changes to
what the browser is
displaying.
Details regarding Incremental, and the virtual-dom diff-and-patch strategy are abstracted away so you’ll rarely need to think about them. However, a good cost model will help you to avoid or debug performance pitfalls. Throughout the rest of this guide, we will endeavor to provide such a cost model.