Get started
From reason-react to Melact in a few minutes.
dune and build.
Step 0
Requirements
You need OCaml ≥ 5.4, Melange ≥ 5.1, dune ≥ 3.16 and Node for the tests.
Melact is not on opam yet: the opam packages melhole, melact and melact-ppx are the next step of the roadmap. Until then, build it from github.com/jongleb/melact.
Step 1
Switch the libraries
Take a reason-react + Melange app and change two lines in its dune files:
- (libraries reason-react)
+ (libraries melact)
- (preprocess (pps reason-react-ppx))
+ (preprocess (pps melact-ppx))and get a build with no React in the bundle and no virtual DOM. Migrating lists what is supported.
Step 2
mlx, Reason or OCaml
melact-ppx takes JSX in mlx, Reason and OCaml [@JSX]. For .mlx files, the dialect goes intodune-project, as in Melact's own repository:
(dialect
(name mlx)
(implementation
(extension mlx)
(merlin_reader mlx)
(preprocess
(run mlx-pp %{input-file}))))Step 3
A component compiles to one template
A whole tree compiles to one template. This mlx counter is one <template> with six holes, the same as the hand-written one:
let[@react.component] make ~initial () =
let count, setCount = React.useState (fun () -> initial) in
let tone = if count < 0 then "negative" else "" in
<div className="counter">
<button onClick=(fun _ -> setCount (fun n -> n - 1))>(React.string "-")</button>
<output className=tone>(React.int count)</output>
<button onClick=(fun _ -> setCount (fun n -> n + 1))>(React.string "+")</button>
<button onClick=(fun _ -> setCount (fun _ -> initial)) disabled=(count = initial)>
(React.string "reset")
</button>
</div>ReactDOM.Client clones the templates into the element, so the code that mounts your app stays as it is. The example lives inexamples/counter-react.
Optional
Server rendering
ReactDOMServer.renderToString and ReactDOM.Client.hydrateRoot work as in React. The code that takes server HTML over costs about a fifth of a small app's bundle, so it is generated only with the ppx's -hydratable flag:
(pps melact-ppx -hydratable)Without it the server's HTML shows until the app mounts over it.
Explore
From the repository
Build the libraries and examples, run the dual test suite, and open the counter:
$ dune build # libraries and examples
$ dune build @runtest-js && npx vitest run
✓ test/view/view_test.mjs (17 tests)
✓ test/view/reconcile_test.mjs (9 tests)
✓ test/react/hooks_test.mjs (15 tests)
✓ test/dual/react/dual_test.mjs (11 tests)
✓ test/dual/melact/dual_test.mjs (11 tests)
$ dune test test/ppx # melact-ppx expect tests
$ npx vite # then open http://localhost:5173/examples/counter/vite.config.js resolves the bare imports Melange emits (melange.js/…) inside each _build/…/output directory, for vitest and for the examples alike.