How to quickly develop a minimal web page (client&server-side)?

Hi all,

I’m quite confortable with Ocaml now.
I would like to create some web pages that use OCaml programs.
I have no experience at all in mixing up Ocaml programs with some web components.

I would like to start with creating a simple web page with some logic all expressed in OCaml. This can be hold by one html file and its css related file.
The public page should have a basic form dedicated to users’ requests.
An admin page will display users’ requests (name/email/request/etc.).
This requires some server-side code.
No more for the moment.

What is be the simplest, quickest and most reliable way to do that?
Which minimat toolset is required?



The easiest way is to use bucklescript.

for very simple case, in theory, you can just use and write ocaml(reason) in the left and get js output in the right and copy it in to a js file and add it to script tag.

in practice, you can also follow :

  1. install bsb

  2. start new project

note: use vscode-reasonml and the transpile is in ‘realtime’.

another step is to use webpack, because if you use stdlib, webpack will help you bundle everything as a js bundle. Depending on how familiar you are with webpack, this can be a little or big step.

for beginner, my recommendation is to use ocaml for your business logic (i.e use ocaml to write js lib) and still use js to interact with browser.

If react is your thing and there is reasonreact waiting for you.


You may like , it’s a port of the Elm Architecture over to OCaml/BuckleScript, allowing you to express everything (views, models, updates) as plain OCaml code.

If you prefer a more “classical” approach to web development, maybe you should take a look at Opium. I haven’t used it myself, but it claims to be “very small and easily learnable”.



It’s nice to get some js code from reasonml or OCaml.
But as I have no specific interest in js and because I have no legacy js code at all, I don’t see the interest in reasonML over using OCaml and targeting js thanks to js_of_ocaml.

In BS documentation Comparison to Js_of_ocaml, I can read that there are three main differences between js_of_ocaml and BS which appear not to be decisive for using BS over js_of_ocaml:

  • js_of_ocaml takes low-level bytecode from OCaml compiler, BuckleScript takes the high-level rawlambda representation from OCaml compiler.
  • js_of_ocaml focuses more on existing OCaml ecosystem (OPAM) while BuckleScript’s major goal is to target NPM/Yarn and existing JS workflows.
  • js_of_ocaml and BuckleScript have slightly different runtime encoding in several places. For example, BuckleScript encodes OCaml Array as JS Array while js_of_ocaml requires its index 0 to be of value 0.

Indeed my main concern is to create the GUI (web pages with some forms, a menu, etc. with interactive features, server side or client side). How do you “use js to interact with browser”?

I’m currently reading the Elm documentation. I don’t see yet a clear difference between Elm Model/Update/View pattern and MVC pattern (Model/View/Controler). Is there any?

view : Model -> Html Msg
The signature is clear. view is a place holder for the UI controls (buttons, text fields, etc.).
Let’s consider that my business objects are clearly defined. It looks like my issue with creating a web interface is mainly about mixing up some html tagged elements that will hold the business objects and their related controls ; css will define the layout. For a simple web page/site, that’s quite fine to create them by hand., even if I’m not used to.
But when the website size is increasing, is there a simple way to create the html skeleton from a web page definition that specifies the layout (how business objetcs are tagged so that css can handle them). Webdevelopers should have an efficient way for doing that.

I had a look at opium. It seems to be mainly dedicated to the business logic and to middleware.
I found quite nothing about creating web UI. In, I just found how some html can be inserted.

I had to fix the two examples to make them work. It was enough to replace opium.unix with opium (in the ocamlbuild command or in the dune file).

Maybe @rgrinberg can give us more explanation about how to make a web UI (a View) with opium?


1 Like

When I looked into it I couldn’t find one either, I guess saying “elm architecture” sounds better and makes it like you really invented something new which is always good for marketing…

If you are just playing around and willing to go a little bit more low-level and unstable API wise you can check out note and brr, here’s the todo mvc example written with these libraries. Mika Illouz also has few examples here.

I hope to be able to to back to it and make a first release later this year but meanwhile you’ll have to pin the repos:

opam pin add
opam pin add

js_of_ocaml vs bucklescript.

Bucklescript compile to javascript file by file and the js is pretty readable. I do not think js_of_ocaml can do that.

if you want write everything in ocaml, js_of_ocaml might be a good choice for you. However, that is not as smooth as bucklescript in term of developer experience. and the learning curve is high. I do not think you can find a framework with this approach and get start in few minutes. (maybe in few hours).

 How do you “use js to interact with browser”?

mainly the DOM interaction part, I could write those in bucklescript and there are bindings for that, but I’d rather to keep them separated.

for opium, your observation is correct. opium is a traditional backend framework.

It looks like there are has two categories for the logic served to a browser:

  • the business logic (e.g. compute the total number of members and their average date of registration).
    -> It seems that js_of_ocaml can easily bring it to the browser (as I don’t need at all js readibilty)

  • the UI Iogic which is mainly DOM interaction as @echowuhao mentioned.
    -> This why I opened this topic (my experience in this field is limited and what is included in UI logic is quite fuzzy in my mind)

Am I right ?

I see two ways for creating the UI logic:

  1. If I know html/css enough, I can create by hand some web pages (html, image and css files). And I can use some usual UI js files that must be reused and not reinvented (menu bar, scrolling, etc.)
    -> It was my initial whish. But I feel that the html/css syntax can quickly become overwhelming.
    And which usual UI js should I use?

  2. Otherwise, as discussed, I can use a library that should make a part of the job for me.
    -> I first have to choose the relevant library.
    The question is: what is done by the library and what should be done by hand?

Can you (or other people) clearly define what is included in UI logic?

I need to create a quite simple and ordinary set of web pages but it must be reliable.
So what do you mean with “unstable API”?

I’ll have a look at note and brr and Mika Illouz’s examples.

The current implementation should be reliable: I’m using it in a deployed app for a customer.

The API is unstable because this is not released software and needs one or more design passes. If you want to use this for a serious project now I would advise against using it, if you are just playing then you can pin the packages to the current head commits.

Thanks for the answer.

Here’s a general question about the style sheet which is a part of the UI.
How are css creation and insertion adressed by all these available libraries?

I’ve just quicky explored before asking this question:

In ReasonML:
I can see nothing about css.
Structural html elements and logic can be mixed up.
See React Greetings and React Hooks examples in; they are exposing html tags and a rendering function ReactDOMRe.renderToElementWithId .
ReasonML and OCaml really look equivalent except that OCaml has simpler syntax with much less parenthesis and curly braces.
When html expressions are replaced with html-typed expressions, OCaml expressions can be more verbous than ReasonML because but I suppose that ReasonML can be made heavier in the same way (see React Hooks example)

In ReasonReact:
In the Style section we can see an example

Since CSS-in-JS is all the rage right now, we’ll recommend our official pick soon. In the meantime, for inline styles, there’s the ReactDOMRe.Style.make API
<div style=(
ReactDOMRe.Style.make(~color="#444444", ~fontSize=“68px”, ())

It looks like there is a CSS-in-JS library trend.
bucklescript-tea proposes a starter kit based on OCaml without css (tcoopman/bucklescript-tea-starter-kit). And a second one based on ReasonML with css. It uses bs-css (feluxe/bs-tea-starter-kit).

@yawaramin: how do you handle the css from OCaml expressions with bucklescript-tea?

I keep on reading.

I would say it depends what you call “minimal Web page”.
If you want a minimal Web page, write it in html.

Il you want client side features in OCaml, Js_of_ocaml or Bucklescript can help. Js_of_ocaml can produce very readable code (with the right options) if that’s what you need, or very optimized code. The advantage of js_of_ocaml is that you want be able to extend your Web app with server side features using Eliom using multi-tier programming.

If you want to quickly develop a minimal Web app, that will evolve in a full featured app, the best solution is to start with Ocsigen Start, that will quickly provide a minimal usable template.


side question: is this the same as your react library? if not what’s different?

Some answers here.


If you want some server features aswell, Eliom is a pretty good pick as it bring altogether server and client programming (+ mobile app target).

Here is an example of a collaborative drawing app in less than 200 loc.

1 Like


Yes they look quite similar from a high level, the difference becomes clearer when you zoom in. What the Elm Architecture does is, it says that an app consists of three parts, an initial model, a view function that takes a model and renders a view, and an update function that takes an action and a current state and returns a new state. There are two key differences from MVC in my mind:

  • Every one of these parts is pure-functional, with no side effects. Elm (and BuckleScript-Tea) manages effects using an effect manager type. All effects are run by a lower-level ‘runtime’. It’s actually a lot like ReactJS is nowadays, with the new Hooks API.
  • This architecture is fractal and self-similar, i.e. you can split an Elm ‘component’ into multiple components that have the exact same design, and keep splitting like this from level to level. As far as I know, MVC architecture does not have this fractal design quality.

I’m not 100% sure I understood this correctly, but what you would do in Elm or similar frameworks is a divide-and-conquer strategy, i.e., define how to render smaller parts of your model, then define how to render their combinations to build up your overall app.

Simple, I don’t write CSS, I let a good CSS component library do that for me :slight_smile: I usually use Bulma, but I’ve also been meaning to check out the US Web Design System

Concretely, you would apply the appropriate classes to the HTML elements, and the above stylesheets would render them nicely for you. It looks something like:

(* *)

let view label =
  Tea.Html.(button [_class "button main"] [text label])

I mean something simple that appears as a simple web page/site with maybe two or three sections (for usability on smartphone) :

In fact, even it’s a simple web page/site I think it’s a real web application with probably the same architecture as a large web site.
There should be some js code on client side and some server-side code to handle the registration data (a file should be enough for storing that - no DB for the moment).
Ocsigen is a very comprehensive and profesional library. I didn’t imagine using it for a “minimal web page”.

Let’s have a look at Ocsigen Start.


In that case I would actually recommend trying out Phoenix LiveView, it’s an Elixir framework that lets you write logic on the backend to drive a web frontend in near-realtime using a dedicated websocket connection. Think React, or Elm, or something similar, only you don’t need to write JavaScript.