Bs-preact: An opinionated Preact v10 binding for (OCaml | ReasonML) + BuckleScript with compile time enforcement of the "Rules of Hooks"


Hi! I just released this project I’ve been working on for more than a month: (Live demos of examples with syntax highlighted source code here.)

This is the Hello World program:

let main = Preact.h1 [] [ Preact.string "Hello, world!" ]

let () =
  match Preact.find "main" with
  | Some element -> Preact.render main element
  | None -> Js.Console.error "<main> not found!"

This is how a useReducer powered Counter component looks like:

module Counter = struct
  type action =
    | Increment
    | Decrement

  let reducer state = function
    | Increment -> state + 1
    | Decrement -> state - 1

  let make =
   fun [@preact.component "Counter"] initial ->
    let[@hook] count, dispatch = P.useReducer reducer initial in
      [ P.button [ P.onClick (fun _ -> dispatch Decrement) ] [ P.string "-" ]
      ; P.string " "
      ; count
      ; P.string " "
      ; P.button [ P.onClick (fun _ -> dispatch Increment) ] [ P.string "+" ]

With the microbundle bundler, the code above compiles to just 4kb (!) of gzipped js. Preact itself is 3kb, so that’s 1kb for the bs-preact runtime and the component above.

A starter project is available with instructions on how to get started:

More examples here. Live demos of examples with syntax highlighted source code here.


Hi. Awesome project!
Why did you choice Preact instead of vanilla React?
Many people wants writing React in pure OCaml without JSX and Elm-like “markup” very good syntax for this purpose (like in your project).


Thanks for the kind words!

The project I originally built this library for was written in Preact. Preact was chosen for that project due to the bundle size difference and the fact that we didn’t need to use any existing React-only library.

I think I might make it React-first in the future considering that replacing React with Preact at build time is much easier than the reverse. I will not drop support for Preact though as that’s what I use in most projects.