The Ocsigen team is very happy to announce the first release of two major new projects:
Ocsigen Start: a Web/mobile application skeleton written with Js_of_ocaml and Eliom. You can use this skeleton as a basis for your own app, or to learn Web/mobile app development in OCaml.
Ocsigen Toolkit: a set of responsive widgets for your mobile and Web applications in OCaml.
Both projects are available via OPAM and released under the LGPL.
Before installing, you can try out a demo of Ocsigen Start. The demo is available
Ocsigen Start provides the basic features for user management (registration, activation links, password recovery, etc.), and some useful libraries. Remove the parts you don’t need for your own app.
Ocsigen Start also contains many examples of code: remote procedure calls, push notifications from the server, reactive pages, database interaction, session data, internationalization, and some widgets from Ocsigen Toolkit.
Ocsigen Toolkit contains common widgets for mobile and Web apps, written natively in OCaml and specifically designed for Eliom’s multi-tier and multi-platform programming style. You can also use them in client-only Js_of_ocaml programs. Many new widgets will be added in future versions.
The Eliom framework is the part of the ocsigen project that aims to provide high level libraries for developing client/server web applications. It contains a language extension of OCaml that allows implementing both the client and the server parts of your application as a single program. It also contains several libraries and utilities to facilitate web programming.
Today, I will not talk about the ocsigen libraries. I will talk solely about the language extension.
The Eliom language extension extends OCaml with various annotations that allows specifying where things are to be defined and executed.
The semantics is that the server part is executed first, then the web page is sent to the client, then the client part is executed. See the documentation for detail on the current extension.
The language extension is currently implemented using a PPX extension and a custom (and a bit sophisticated) compilation scheme. Note here that I used the word “language” extension on purpose: this is not a simple syntax extension, the Eliom language has its own type system, semantics and compilation scheme, which are extensions of the OCaml ones.
The current implementation of our language, based on PPX, started to show its limits in terms of flexibility, convenience and with respect to the safety guarantees it can provide. This is why I started, as part of my PhD thesis, to redesign and improve it.
Our first goal was to formalize the Eliom language as an extension of the OCaml language. Formalizing the language allowed us to better understand its type system and semantics, which led to various improvements and bug fixes. The formalization was published in APLAS 2016. In this paper, we present a (rather simple) type system based on two distinct type universes and the notion of converters, that allows passing values from the server to the client. We also show that the intuitive semantics of Eliom, that server code is executed immediately and client code is executed later in the exact same order it was encountered, does correspond to the compilation scheme used to slice Eliom programs into a server program and a client program.
In the the current implementation, when passing
a server value of type
Foo.t to the client. It also has type
but the type is now the one available on the client. The actual object
can also be transformed while passing the client/server boundary using
wrappers. Unfortunately, this API is very difficult to use, not
flexible and quite unsafe. Instead, we propose to use converters.
Converters can be though as a pair of function: a server serialization
ty_server -> string and a client deserialization function
string -> ty_client (the actual implementation will be a bit different to make (de)serializer composable).
The correctness of a converter depends of course on the good behavior of these
two functions, but the language guarantees that they will be used together
properly and each sides will properly respect the types of the converter.
By using converters, we can provide a convenient programming model and make Eliom much easier to extend. We demonstrated this with multiple examples in another paper published in IFL 2016. Unfortunately, a proper implementation of converters is only possible with some form of ad-hoc polymorphism, which involve using modular implicits.
In order to actually implement all these new things, I started to work on an extension of the OCaml compiler capable of handling the Eliom language constructs. Working directly in the compiler has several advantages:
The current work-in-progress compiler is available in the repository ocsigen/ocaml-eliom. A minimal runtime, along with various associated tools are available in ocsigen/eliomlang. A (perpetually broken) playground containing an extremely bare-bone website using eliomlang without the complete framework is available in ocsigen/eliomlang-playground.
Finally, the work on using this new compiler to compile the Eliom framework can be followed via this pull-request.
A more in-depth presentation of the Eliom language can be found here. The APLAS paper is quite formal and is mostly aimed at people that want to really understand the minute details of the language. The IFL paper, on the other hand, should be accessible to most OCaml programmers (even those who don’t know Eliom) and demonstrates how to use the new Eliom constructs to build nice, tierless and typesafe libraries for client/server web programming.
The work on the Eliom language is far from done. A current area of work is to extend the OCaml module language to be aware of the Eliom annotations. A particularly delicate (but promising!) area is the ability to use Eliom annotations inside functors. A second area of work is that of stabilizing, debugging and documenting the patched compiler. Finally, a difficulty raised by this new compiler is that existing build systems, and in particular ocamlbuild, do not handle the Eliom compilation scheme very well. Some details on this can be found here.
I wish this progress report has awaken your appetite for well-typed and modular tierless programming in OCaml. I hope I will be able to share more news in a few months.
Happy Eliom programming!
To this end:
[@deprecated]), especially for upcoming breaking changes. This required dropping support for OCaml 4.01.
If you are releasing a package to OPAM that depends on Lwt, it is not recommended to constrain Lwt to its current major version. A major release of Lwt will break only a few APIs, and your package is likely not to be affected – if it is, you will be notified. You may, however, wish to constrain Lwt to a major version in your private or production code.
lwtis getting rid of some optional dependencies in 3.0.0, which are now installable through separate OPAM packages
lwt_react. This is to reduce recompilation of Lwt when installing OPAM packages
'a Lwt.tare now called promises rather than threads. This should eliminate a lot of confusion for beginners.
Lwt 2.7.0 also has a number of more ordinary changes, such as bug fixes
and the addition of bindings to
readv. See the full
I am working on an all-new manual, including fully rewritten API documentation with examples. It should be ready towards the end of winter.
My hope is that all the above allows Lwt to be taken progressively into the future, at the same time making development more open and more humane.
Discuss on reddit!
New features include a friendlier service API that retains the expressive power of our service system. Additionally, Eliom can now be used to build cross-platform Web/mobile applications (Android, iOS, …).
Eliom is a framework for developing client/server web applications. Both the server and the client parts of the application are written in OCaml, as a single program. Communication between server and client is straightforward, e.g., one can just call a server-side function from client-side code.
Eliom makes extensive use of the OCaml language features. It provides advanced functionality like a powerful session mechanism and support for functional reactive Web pages.
Services are a key concept in Eliom, used for building the pages that are sent to the user, for accessing server-side data, for performing various actions, and so on. Eliom 6.0 provides a friendlier API for defining and registering services, thus making Eliom more approachable.
Eliom 6.0 allows one to build applications for multiple mobile platforms (including iOS, Android, and Windows) with the same codebase as for a Web application, and following standard Eliom idioms.
To achieve this, we have made available the Eliom service APIs on the client. Thus, the user interface can be produced directly on the mobile device, with remote calls only when absolutely necessary.
Eliom 6.0 supports the last 3 major versions of OCaml (4.02 up to 4.04). Additionally, Eliom is compatible with and builds on the latest Ocsigen releases, including Ocsigen Server 2.8, Js_of_ocaml 2.8.x, and TyXML 4.0.x.
It is with great pleasure that we are announcing the release of TyXML 4.0.0. The major features of this new release are a new PPX syntax extension that allows to use the standard HTML syntax and an improved user experience for both old and new TyXML users.
TyXML is a library for building statically correct HTML5 and SVG documents. It provides a set of combinators which use the OCaml type system to ensure the validity of the generated document. TyXML’s combinators can be used to build textual HTML and SVG, but also DOM trees or reactive interfaces, using Eliom and Js_of_ocaml.
It is now possible to use the standard HTML syntax:
The HTML and SVG combinators have received numerous improvements to make them more consistent and easier to use. This means that several modules and functions have been renamed and some types have been changed, which breaks compatibility with previous TyXML versions.
A healthy amount of new elements and attributes.
The full changelog is available here.
This new version breaks compatibility. Compatible versions of
js_of_ocaml and Eliom are available in the respective
js_of_ocaml version should be released shortly™.
TyXML 4.0.0 is only available on OCaml >= 4.02.
While nothing is decided yet, some work has already started to enhance the syntax extension with type safe templating.
Happy HTML and SVG hacking!
This is the end of the tutorial about writing a collaborative Web drawing in OCaml. Have a look at the full tutorial if you haven’t read the first part or if you want a version with full colors and links.
We will now see how to draw on the canvas, program mouse events with Lwt, and do server to client communication on a bus.
We now want to draw something on the page using an HTML5 canvas. The
drawing primitive is defined in the client-side function called
draw that just draws a line between two given points in a canvas.
To start our collaborative drawing application, we define another
init_client, which just draws a single
line for now.
Here is the (full) new version of the program:
Here we use the function
from Js_of_ocaml’s library to convert an OCaml string
into a JS string.
What sounds a bit weird at first, is a very convenient practice for processing request in a client-server application: If a client value is created while processing a request, it will be evaluated on the client once it receives the response and the document is created; the corresponding side effects are then executed. For example, the line
creates a client value for the sole purpose of performing side
effects on the client. The client value can also be named (as
opposed to ignored via
_), thus enabling server-side
manipulation of client-side values (see below).
(Lwt, Mouse events with Lwt)
We now want to catch mouse events to draw lines with the mouse like
with the brush tools of any classical drawing application. One
example by using function
that is the Js_of_ocaml’s equivalent of
addEventListener. However, this solution is at least as verbose
library provides a much easier way to do that with the help of Lwt.
init_client of the previous example by the
following piece of code, then compile and draw!
We use two references
y to record the last mouse
position. The function
set_coord updates those references from
mouse event data. The function
compute_line computes the
coordinates of a line from the initial (old) coordinates to the new
coordinates–the event data sent as a parameter.
The last four lines of code implement the event-handling loop. They
can be read as follows: for each
mousedown event on the canvas,
line (this will draw a dot), then
behave as the
first of the two following lines that terminates:
Functions in Eliom and Js_of_ocaml which do not implement just a
computation or direct side effect, but rather wait for user activity,
or file system access, or need a unforeseeable amount of time to return
are defined with Lwt; instead of returning a value of type
they return an Lwt thread of type
The only way to use the result of such functions (ones that return
values in the Lwt monad), is to use
It is convenient to define an infix operator like this:
Then the code
is conceptually similar to
but only for functions returning a value in the Lwt monad.
For more clarity, there is a syntax extension for Lwt, defining
let%lwt to be used instead of
let for Lwt functions:
Lwt.return creates a terminated thread from a value:
Lwt.return : 'a -> 'a Lwt.t Use it when you must
return something in the Lwt monad (for example in a service handler,
or often after a
An Eliom application is a cooperative program, as the server must be able to handle several requests at the same time. Ocsigen is using cooperative threading instead of the more widely used preemptive threading paradigm. It means that no scheduler will interrupt your functions whenever it wants. Switching from one thread to another is done only when there is a cooperation point.
We will use the term cooperative functions to identify functions
implemented in cooperative way, that is: if something takes
(potentially a long) time to complete (for example reading a value
from a database), they insert a cooperation point to let other threads
run. Cooperative functions return a value in the Lwt monad
(that is, a value of type
'a Lwt.t for some type
Lwt.return do not introduce cooperation points.
In our example, the function
Lwt_js_events.mouseup may introduce
a cooperation point, because it is unforeseeable when this event
happens. That’s why it returns a value in the Lwt monad.
Using cooperative threads has a huge advantage: given that you know precisely where the cooperation points are, you need very few mutexes and you have very low risk of deadlocks!
Using Lwt is very easy and does not cause trouble, provided you never use blocking functions (non-cooperative functions). Blocking functions can cause the entre server to hang! Remember:
Lwt_unixinstead of module
Lwt.binddoes not introduce any cooperation point.
allows easily defining event listeners using Lwt. For example,
Lwt_js_events.click takes a
DOM element and returns an Lwt thread that will wait until a click
occures on this element.
Functions with an ending “s” (
Lwt_js_events.mousedowns, …) start again waiting after the
Lwt.pick behaves as the first thread
in the list to terminate, and cancels the others.
(Client server communication)
In order to see what other users are drawing, we now want to do the following:
We first declare a type, shared by the server and the client, describing the color (as RGB values) and coordinates of drawn lines.
We annotate the type declaration with
[@@deriving json] to allow
type-safe deserialization of this type. Eliom forces you to use this
in order to avoid server crashes if a client sends corrupted data.
This is defined using a JSON plugin for
ppx_deriving, which you
need to install. You need to do that for each type of data sent by the
client to the server. This annotation can only be added on types
containing exclusively basic types, or other types annotated with
Then we create an Eliom bus to broadcast drawing events to all client
with the function
This function take as parameter the type of
values carried by the bus.
To write draw commands into the bus, we just replace the function
Finally, to interpret the draw orders read on the bus, we add the
following line at the end of function
Now you can try the program using two browser windows to see that the lines are drawn on both windows.
Eliom provides multiple ways for the server to send unsolicited data to the client:
Eliom_bus.tare broadcasting channels where client and server can participate (see also «a_api project=”eliom” subproject=”client” | type Eliom_bus.t » in the client API).
Eliom_reactallows sending React events from the server to the client, and conversely.
Eliom_comet.Channel.t are one-way communication channels
allowing finer-grained control. It allows sending
to the client.
Eliom_bus are implemented over
It is possible to control the idle behaviour with module
(Widgets with Ocsigen-widgets)
In this section, we add a color picker and slider to choose the size
of the brush. For the colorpicker we used a widget available in
To install Ocsigen widgets, do:
opam pin add ocsigen-widgets https://github.com/ocsigen/ocsigen-widgets.git opam install ocsigen-widgets
Makefile.options, created by Eliom’s distillery, add
ocsigen-widgets.client to the
CLIENT_PACKAGES := ... ocsigen-widgets.client
To create the widget, we add the following code in the
init_client immediately after canvas configuration:
We subsequently add a simple HTML5 slider to change the size of the
brush. Near the
canvas_elt definition, simply add the following
Form.int is a typing information telling that this input takes
an integer value. This kind of input can only be associated to
services taking an integer as parameter.
We then add the slider to the page body, as follows:
To change the size and the color of the brush, we replace the last
line of the function
Finally, we need to add a stylesheet in the headers of our page. To
easily create the
head HTML element, we use the function
You need to install the corresponding stylesheets and images into your
project. The stylesheet files should go to the directory
File graffiti.css is a custom-made CSS file.
You can then test your application (
Ocsigen-widgets is a Js_of_ocaml library providing useful widgets for your Eliom applications. You can use it for building complex user interfaces.
(Services sending other data types)
To finish the first part of the tutorial, we want to save the current drawing on server side and send the current image when a new user arrives. To do that, we will use the Cairo binding for OCaml.
For using Cairo, first, make sure that it is installed (it is
cairo2 via OPAM). Second, add it to the
SERVER_PACKAGES in your
SERVER_PACKAGES := ... cairo2
draw_server function below is the equivalent of the
draw function on the server side and the
function outputs the PNG image in a string.
We also define a service that sends the picture:
Eliom_registration defines several modules with
registration functions for a variety of data types. We have already
Eliom_registration.String sends arbitrary byte output
(represented by an OCaml string). The handler function must return
a pair consisting of the content and the content-type.
There are also several other output modules, for example:
Eliom_registration.Fileto send static files
Eliom_registration.Redirectionto create a redirection towards another page
Eliom_registration.Anyto create services that decide late what they want to send
Eliom_registration.Ocamlto send any OCaml data to be used in a client side program
Eliom_registration.Actionto create service with no output (the handler function just performs a side effect on the server) and reload the current page (or not). We will see an example of actions in the next chapter.
We now want to load the initial image once the canvas is created. Add the following lines just between the creation of the canvas context and the creation of the slider:
You are then ready to try your graffiti-application by
Note, that the
Makefile from the distillery automatically adds
the packages defined in
SERVER_PACKAGES as an extension in your
<extension findlib-package="cairo2" />
This post (and the following one) is a step by step tutorial about client-server Web applications in OCaml. You can find the full tutorial here. It introduces the basics of Web programming with OCaml: type-checking HTML, defining services, using lightweight threads, writing a client-server program …
We will write a collaborative drawing application. It is a client-server Web application displaying an area where users can draw using the mouse, and see what other users are drawing at the same time and in real-time.
The application is running online here.
To get started, we recommend using Eliom’s distillery, a program which creates scaffolds for Eliom projects. The following command creates a very simple project called graffiti in the directory graffiti:
$ eliom-distillery -name graffiti -template basic.ppx -target-directory graffiti
(Services, Configuration file, Static validation of HTML)
Our web application consists of a single page for now. Let’s start by creating a very basic page. We define the service that will implement this page by the following declaration:
If you are using eliom-distillery just replace the content of the eliom-file by the above lines and run
$ make test.byte
This will compile your application and run ocsigenserver on it. (Refer to the manual on how to compile your project “by hand”.)
Your page is now available at URL
Unlike typical web programming techniques (CGI, PHP, …), with Eliom you do not need to write one file per URL. The application can be split into multiple files as per the developer’s style. What matters is that you eventually produce a single module (*.cmo or *.cma) for the whole website.
Module Eliom_service allows to create new entry points to your web site, called services. In general, services are attached to a URL and generate a web page. Services are represented by OCaml values, through which you must register a function that will generate a page.
~path corresponds to the URL where you want to attach your service. It is a list of strings. The value
["foo"; "bar"] corresponds to URL
["dir"; ""] corresponds to URL
dir/ (that is: the default page of the directory dir).
In the directory of the project created by the Eliom-distillery, you can find the file
graffiti.conf.in. This file is used in conjunction with the variables in Makefile.options to generate the ocsigenserver configuration file.
Once you start up your application via
make test.byte, the configuration file becomes available at
local/etc/graffiti/graffiti-test.conf. It contains various directives for Ocsigen server (port, log files, extensions to be loaded, etc.), taken from Makefile.options, and something like:
<host> <static dir="static" /> <eliommodule module="/path_to/graffiti.cma" /> <eliom /> </host>
<eliommodule ... /> asks the server to load Eliom module
graffiti.cma, containing the Eliom application, at startup and
attach it to this host (and site).
<static ... /> (staticmod) and
<eliom /> are called successively:
/path_to/graffiti/staticwill be served,
There are several ways to create pages for Eliom. You can generate pages as strings (as in other web frameworks). However, it is preferable to generate HTML in a way that provides compile-time HTML correctness guarantees. This tutorial achieves this by using module Eliom_content.Html5.D, which is implemented using the TyXML library. The module defines a construction function for each HTML5 tag.
Note that it is also possible to use the usual HTML syntax directly in OCaml.
The TyXML library (and thus Eliom_content.Html5.D) is very strict and compels you to respect HTML5 standard (with some limitations). For example if you write:
You will get an error message similar to the following, referring to the end of line 2:
Error: This expression has type ([> `PCDATA ] as 'a) Html5.elt but an expression was expected of type Html5_types.head_content_fun Html5.elt Type 'a is not compatible with type Html5_types.head_content_fun = [ `Base | `Command | `Link | `Meta | `Noscript of [ `Link | `Meta | `Style ] | `Script | `Style ] The second variant type does not allow tag(s) `PCDATA
Html5_types.head_content_fun is the type of content allowed inside
<meta>, etc.). Notice that
<PCDATA (i.e. raw text) is not included in this polymorphic variant type.
Most functions take as parameter the list representing its contents. See other examples below. Each of them take un optional
?a parameter for optional HTML attributes. Mandatory HTML attributes correspond to mandatory OCaml parameters. See below for examples.
Important warning: All the functions you write must be written in a cooperative manner using Lwt. Lwt is a convenient way to implement concurrent programs in OCaml, and is now also widely used for applications unrelated to Ocsigen.
For now we will just use the
Lwt.return function as above. We will come back to Lwt programming later. You can also have a look at the Lwt programming guide.
To create our first service, we used the function Eliom_registration.Html5.register_service, as all we wanted to do was return HTML5. But we actually want a service that corresponds to a full Eliom application with client and server parts. To do so, we need to create our own registration module by using the functor
It is now possible to use
My_app for registering our main service
(now at URL
After running again make test.byte, and visiting
http://localhost:8080/, the browser will load the file
graffiti.js, and open an alert-box.
At the very toplevel of your source file (i.e. not inside modules or other server- /client-parts), you can use the following constructs to indicate which side the code should run on.
[%%client ... ]: the list of enclosed definitions is client-only code (similarly for
[%%server ... ]). With
[%%shared ... ], the code is used both on the server and client.
let%shared: same as above for a single definition.
[%%shared.start]: these set the default location for all definitions that follow, and which do not use the preceding constructs.
If no location is specified, the code is assumed to be for the server.
The above constructs are implemented by means of PPX, OCaml’s new mechanism for implementing syntax extensions. See Ppx_eliom for details.
Client parts are executed once, when the client side process is launched. The client process is not restarted after each page change.
Additionally, it is possible to create client values within the server code by the following quotation:
typ is the type of an expression
expr on the client. Note, that such a client value is abstract on the server, but becomes concrete, once it is sent to the client with the next request.
typ can be ommitted if it can be inferred from the usage of the client value in the server code.)
Client values are executed on the client after the service returns. You can use client values when a service wants to ask the client to run something, for example binding some event handler on some element produced by the service.
obj##m a b cto call the method
obj##.mto get a property,
obj##.m := eto set a property, and
More information can be found in the Js_of_ocaml manual, in the module Ppx_js.
(Executing client side code after loading a page, Sharing server side values, Converting an HTML value to a portion of page (a.k.a. Dom node), Manipulating HTML node ‘by reference’)
The client side process is not strictly separated from the server side. We can access some server variables from the client code. For instance:
Here, we are increasing the reference count each time the page is accessed. When the page is loaded and the document is in-place, the client program initializes the value inside
[%client ... ], and thus triggers an alert window. More specifically, the variable
c, in the scope of the client value on the server is made available to the client value using the syntax extension
~%c. In doing so, the server side value
c is displayed in a message box on the client.
###Injections: Using server side values in client code
Client side code can reference copies of server side values using syntax
~%variable. Values sent that way are weakly type checked: the name of the client side type must match the server side one. If you define a type and want it to be available on both sides, declare it in
[%%shared ... ]. The Eliom manual provides more information on the Eliom’s syntax extension and its compilation process.
Note that the value of an injection into a
[%%client ... ] section is sent only once when starting the application in the browser, and not synced automatically later. In contrast, the values of injections into client values which are created during a request are sent alongside the next response.
In next tutorial, we will turn the program into a collaborative drawing application, and learn:
The impatient can find the full tutorial here.
This short tutorial is an example of client-server Eliom application. It gives an example of client-server widgets. You can find the original version of this tutorial (and many others) here.
It is probably a good starting point if you know OCaml well, and want to quickly learn how to write a client-server Eliom application with a short example and concise explanations. For more detailed explanations, see the “Graffiti” tutorial, or read the manuals.
This tutorial also shows that it is possible to use the same code to build the widget either on client or server side.
We choose a very simple widget, that could be the base for example for implementing a drop-down menu. It consists of several boxes with a title and a content. Clicking on the title opens or closes the content. Furthermore, it is possible to group some of the boxes together to make them behave like radio buttons: when you open one of them, the previously opened one is closed.
The following code defines a client-server Web application with only one service, registered at URL / (the root of the website).
The code also defines a client-side application (section
[%%client ... ]) that appends a client-side generated widget to the page. Section
[%%shared ... ] is compiled on both the server and client side programs. Alternatively, you can write
let%shared (default) to define values on client side, on server side, or on both sides.
To compile it, first create a project by calling
eliom-distillery -name ex -template basic.ppx
The name of the project must match the name given to the functor
After you adapt the file
ex.eliom, you can compile by calling make, and run the server by calling
make test.byte. Download the CSS file and place it in directory
static/css. Then open a browser window and go to URL
This section gives very quick explanations on the rest of the program. For more detailed explanations, see the tutorial for the graffiti app or the manual of each of the projects.
##is used to call a JS method from OCaml and
##.to access a JS object field (See Js_of_ocaml’s documentation: Ppx_js).
Lwtis the concurrent library used to program threads on both client and server sides. The syntax
let%lwt a = e1 in e2allows waiting (without blocking the rest of the program) for an Lwt thread to terminate before continuing.
e2must ben a Lwt thread itself.
Lwt.returnenables creating an already-terminated Lwt thread.
Lwt_js_eventsdefines a convenient way to program interface events (mouse, keyboard, …). For example,
Lwt_js_events.onloadis a Lwt thread that waits until the page is loaded. There are similar functions to wait for other events, e.g., for a click on an element of the page, or for a key press.
To make the widget work, we must bind the click event. Replace function
mywidget by the following lines:
clicksis used to bind a handler to clicks on a specific element.
Lwtthread asynchronously (without waiting for its result).
Lwt_js_events.clicks elt fcalls function
ffor each mouseclick on element
Js.to_boolare conversion functions between OCaml values and JS values.
The following version of the program shows how to generate the widget on server side, before sending it to the client.
The code is exactly the same, with the following modifications:
[%client (... : unit) ]. This code will be executed by the client-side program when it receives the page. Note that you must give the type (here
unit), as the type inference for client values is currently very limited. The client section may refer to server side values, using the
~%xsyntax. These values will be serialized and sent to the client automatically with the page.
If you make function
mywidget shared, it will be available both on server and client sides:
To implement this, we record a client-side reference to a function for closing the currently opened window.
Now we want to enable several sets of widgets in the same page. A single reference no longer suffices. In the following version, the server-side program asks the client-side program to generate two different references, by calling function
new_set. This function returns what we call a client value. Client values are values of the client side program that can be manipulated on server side (but not evaluated). On server side, they have an abstract type.
An important feature missing from this tutorial is the ability to call server functions from the client-side program (“server functions”). You can find a quick description of this in this mini HOWTO or in Eliom’s manual.
For many applications, you will need several services. By default, client-side Eliom programs do not stop when you follow a link or send a form. This enables combining rich client side features (playing music, animations, stateful applications …) with traditional Web interaction (links, forms, bookmarks, back button …). Eliom proposes several ways to identify services, either by the URL (and parameters), or by a session identifier (we call this kind of service a coservice). Eliom also allows creating new (co-)services dynamically, for example coservices depending on previous interaction with a user. More information on the service identification mechanism in Eliom’s manual.
Eliom also offers a rich session mechanism, with scopes (see Eliom’s manual).
Following last week release, I’m starting today a series of tutorials about the Ocsigen framework. For the impatient, most of these tutorials are already available on Ocsigen’s Web site.
In this first tutorial, we show how to use the Ocsigen framework (mainly Eliom) to write a lightweight Web site by generating pages using OCaml functions. Even though Eliom makes it possible to write complete client-server Web and mobile apps, you can still use Eliom even if you don’t need all these features (for example if you don’t want HTML type checking or client side features). Besides, this will allow you to extend your Web site in a full Web application if you need, later on. This tutorial is also a good overview of the basics of Eliom.
The following code shows how to create a service that answers requests at URL
http://.../aaa/bbb, by invoking an Ocaml function
f of type:
f generates HTML as a string, taking as argument the list of URL parameters (GET parameters).
Eliom_paramer.any means that the service takes any GET parameter.
We recommend to use the program eliom-distillery to generate a template for your application (a Makefile and a default configuration file for Ocsigen Server).
$ eliom-distillery -name mysite -template basic.ppx -target-directory mysite
Put the piece of code above in file mysite.eliom, compile and run the server by doing:
$ make test.byte
Your page is now available at URL http://localhost:8080/aaa/bbb.
If you dont want to use the Makefile provided by eliom-distillery, just replace mysite.eliom by a file mysite.ml, compile and run with
$ ocamlfind ocamlc -package eliom.server -thread -c mysite.ml $ ocsigenserver -c mysite.conf
mysite.conf is adapted from
local/etc/mysite/mysite-test.conf by replacing
mysite.cma by your cmo.
Services using the POST HTTP method are created using the function
Eliom_service.Http.post_service. To create a service with POST parameters, first you must create a service without POST parameters, and then the service with POST parameters, with the first service as fallback. The fallback is used if the user comes back later without POST parameters, for example because he put a bookmark on this URL.
That is probably all you need for a very basic Web site in OCaml. But Ocsigen provides many tools to write more advanced Web sites and applications:
Instead of generating HTML in OCaml strings, we highly recommend to use
typed HTML. It is very easy to use, once you have learned the basics,
and helps a lot to efficiently write modular and valid HTML.
To do this, use module
for more information, a comprehensive documentation
and a more advanced manual
Have a look at Eliom’s API documentation to see other kinds of services,
to create HTTP redirections.
Eliom also has a way to typecheck forms and GET or POST parameters. By giving a description of the parameters your service expects, Eliom will check their presence automatically, and convert them for you to OCaml types. See this tutorial and this manual page.
Eliom also has other ways to identify services (besides just the PATH in the URL). For example Eliom can identify a service just by a parameter (whatever the path is). This is called non-attached coservices and this makes it possible for instance to have the same feature on every page (for example a connection service). See this tutorial and this manual page.
Another interesting feature of Eliom is its session model, that uses a very simple interface to record session data server-side. It is even possible to choose the scope of this data: either a browser, or a tab, or even a group of browsers (belonging for instance to a same user). See this section and the beginning of this manual page.
We suggest to continue your reading by one of these tutorials:
We are excited to announce the releases of
These releases are the result of many months of work by the Ocsigen team, and bring a range of improvements.
Eliom 5.0 comes with a PPX-based language (for OCaml 4.02.x). This follows our PPX extensions for js_of_ocaml and Lwt. The new syntax is more flexible than our previous Camlp4-based one, and we recommend it for new projects. Nevertheless, the Camlp4-based syntax remains available.
Recent versions of Eliom provided client-side support for (functional) reactive programming. Eliom 5.0 additionally supports “shared” (client-server) reactive programming, where the reactive signals have meaning both on the server and the client. This means that the initial version of the page is produced (on the server) with the same code that takes care of the dynamic updates (on the client).
js_of_ocaml provides a new JSON plugin for ppx_deriving. This can be used for serializing OCaml data structures to JSON in a type-safe way. The plugin remains compatible with its Camlp4-based predecessor with respect to the serialization format.
In addition to providing various fixes, we have improved the performance of various Ocsigen components. Notably:
A range of patches related to request data result in measurably smaller size for the produced pages.
The js_of_ocaml compiler becomes faster via improvements in bytecode parsing.
reactiveData employs diffing to detect data structure changes, leading to more localized incremental updates.
In this post, we outline the architecture of our implementation, with a particular emphasis on how it applies MVC and FRP concepts.
MVC, which stands for Model-View-Controller, is a software architecture very commonly used for implementing user interfaces. MVC divides an application into three components:
the Model manages the data, logic and rules of the application;
the Controller manages events from the view, and accordingly updates the model;
the View generates an output presentation (a web page for instance) based on the model data.
For the Todo application, we have three corresponding OCaml
Model mainly contains the task list and the new
task field value. It uses
Deriving_Json to convert
the data to JSON and vice versa, in order to be able to save and
restore the application state. This module is otherwise written with
basic OCaml code.
Controller produces new models
according to the actions it receives. Whenever a new model is built,
the model becomes the new reactive signal value. We will elaborate on
this point later.
View builds the HTML to display the
page. It receives as input the dynamic data from the model. The HTML
also contains the event management code needed to emit the
Besides these three MVC modules, the application uses three
contains the functions to read and write a string value in the browser
local storage. This module is used to save and restore the application
data in JSON
contains all the actions available from the user
contains a single function to ease the creation of a reactive list via
React is an OCaml module for functional reactive programming
(FRP). In our TodoMVC example,
React provides a way to
automatically refresh the view whenever a new model is built by the
controller. To achieve this goal, the application uses a reactive
signal which carries the model values (which vary over time). The
model value may initially be equal to the empty model. When
this value is modified by the controller, i.e., after a new model
has been generated, the view automatically refreshes its reactive
The following figure shows what happens when the user interacts with the application, e.g., by adding a new task, or by clicking on a checkbox to select a specific task:
the view sends the action to the controller;
the controller gets the current model from the reactive signal, and builds a new model accordingly to the action;
the controller sets this new model as the new reactive signal value;
the view reacts to the newly-available model (new signal value) and updates itself with the corresponding data.
We proceed to describe our implementation of the above scheme, with an emphasis on the reactive features.
The main function creates the reactive signal with an initial
(possibly empty) model. The
m value is of type
React.S.create returns a tuple, the first part of which is a
primitive signal; the second part is a function used by the controller
to set a new model as the new signal value.
We first explain how the CSS style of a HTML node becomes
reactive. In the Todo application, the task list is
displayed in a
<section> HTML tag. The CSS style of this HTML node
visibility: hidden; if the tasks list is empty, and
visibility: visible; otherwise (i.e., if the number of tasks is
greater than zero). The style attribute of this
<section> node must
therefore change according to the model content:
We use the
Tyxml_js module to safely build the HTML
code. The first thing to note is that we use the reactive
submodule, not the plain
Html5 submodule. The
implements a reactive attribute; it expects a reactive signal as its
argument. Here we use
React.S.map, which has the signature
'b) -> 'a React.signal -> 'b React.signal. The first argument to
map is the
As you can see,
css_visibility receives a model
m as its
argument. When wrapped by
React.S.map as above,
operates on signals. The function returns the right style, depending
on whether the list of tasks is empty or not.
The second argument to
React.S.map is the value named
r, which is
the primitive signal.
r is the first value returned by the
Each time the signal value gets updated by the controller, the
css_visibility function is automatically called with the new signal
value (a new model) as its argument, and the style attribute is
Reactive attributes alone would not suffice to build a user
interface. We also need a reactive list of child nodes. Such a list is
for example needed to display the task list. (The source code section
is the same as for the first
is a list of
<li> nodes contained in a
<ul> node. We accordingly
have a reactive node, as follows:
As before, we use the
R.Html5 module. This time we do not use
R.Html5 to build an attribute, but rather a (
contains the node’s children:
We create the reactive list via the helper module
ReactList. As for the previous example, we use
React.S.map to build a reactive signal,
r being again the
primitive signal. The
visible_tasks function generates the
elements from the task list, filtered by the current selected
Following the same principle as for the reactive attribute, each time
the signal value gets updated by the controller, the
<li> nodes are
You may have noticed that the code includes the following types:
These types are used whenever type annotations are required, e.g.,
update function from the
Elm is a functional programming language dedicated to frontend web application development. Elm was designed by Evan Czaplicki. The language should feel familiar to OCaml programmers.
Our TodoMVC example is based on the Elm
implementation, which follows
the structure used in all Elm
model, an update function, and a view. Like Elm, our example uses the
functional reactive programming style, enabled in our case by the
React library and the reactive modules
The combination of OCaml, js_of_ocaml, and functional reactive programming provides a killer feature combination for building rich web clients. Additionally, OCaml static typing can provide compile-time HTML validity checking (via TyXML), thus increasing reliability.
We are happy to announce the releases of
We also welcome a new member in the ocsigen team, Vasilis Papavasileiou.
Key changes in the various releases:
PPX support for js_of_ocaml with OCaml >= 4.02.2. See documentation here.
This was also the occasion to introduce a new syntax for object literals, and to improve the Camlp4 syntax (w.r.t. to locations). Both syntaxes emit the same code, and are perfectly compatible.
Support for dynlink in js_of_ocaml.
Logging improvements in Eliom and Server, in particular on the client side.
A healthy amount of bugfixes.
The next releases will probably see major changes. The current plan is:
Replace Server’s internals with cohttp, as part of our move towards Mirage-compatible libraries. See here.
Shared_react, which allows to build reactive pages from server side. See here.
PPX for Eliom.
Support for async/core in js_of_ocaml.
Have fun with Ocsigen!
The Ocsigen project finally has a blog. We are planning to publish news from the wider Ocsigen community, tutorials, and more.
Ocsigen encompasses the building blocks that you need in order to efficiently develop Web applications in OCaml. Among other libraries and tools, Ocsigen provides:
Ocsigen Server, which is a web server implemented in OCaml;
Lwt, which is a cooperative thread library for OCaml;
TyXML, which is a library for generating valid HTML and SVG content; last but not least,
Eliom, which puts everything together to provide a modern language for developing web applications, with tight integration between client and server.
Happy hacking, and stay tuned!