Native implementation of React's server-side rendering (SSR) and React Server Components (RSC) architecture for Reason.
Designed to be used with reason-react and Melange. Together it enables developers to write efficient React components using a single language, while compiling into native code and JavaScript.
- Server-side rendering HTML with
ReactDOM.renderToString/ReactDOM.renderToStaticMarkup - Server-side rendering streaming HTML with
ReactDOM.renderToStream(exactly likerenderToReadableStream) - Includes
React.SuspenseandReact.use()implementations - server-reason-react-ppx - A ppx transformation to support JSX on native
- All reason-react interface is either implemented or stubbed (some of the methods, like React.useState need to be stubbed because they aren't used on the server!)
- React Server Components - A ReactServerDOM module for streaming RSC payload, an esbuild plugin to enhance the bundle with client-components mappings, a Dream middleware to serve the RSC endpoint and an implementation of a router
Warning: This repo contains a few parts that are considered experimental and there's no guarantee of stability. Most of the stable parts are used in production at ahrefs.com. Check each module's documentation for more details.
There are plenty of motives for it, the main one is that ahrefs (the company I work for) needs it. We use OCaml for the backend and Reason (with React) for the frontend. The second one is probably because is crazy fun, and the real but the serious lists was mostly:
- Use the same language for both server and client
- Embrace server-client integrations such as type-safe routing, JSON decoding/encoding, sharing types and logic all in functional programming patterns
- Native performance is much better than JavaScript performance (Node.js, Bun, Deno)
- Native development provides a safer architecture
- Using the brilliant pieces from the React.js ecosystem
- Exploration of OCaml effects and React
- Further exploration with OCaml multicore, direct-style and concurrency with React features such as async components, React.use or Suspense
Explained more about the motivation in this blog post and also in my talk about Universal react in OCaml at fun-ocaml 2024 and Server side rendering React natively with Reason at ReactAlicante 2023
Aside from the core (React, ReactDOM and ReactServerDOM), server-reason-react repo contains some common melange libraries to ensure components are universal. Some of them are reimplementations in native of those libraries, and others are new implementations. Currently they are part of the repository, but eventually will be moved out to their own opam packages and repositories.
| Name | Description | Melange equivalent library |
|---|---|---|
server-reason-react.browser_ppx |
A ppx to discard code for each platform with different attributes: let%browser_only, switch%platform and @platform |
|
server-reason-react.url_js and server-reason-react.url_native |
Universal URL module: binds to window.URL in browser, implemented with opam-uri in native |
|
server-reason-react.melange_ppx |
A ppx to add the melange attributes to native code | melange.ppx |
server-reason-react.promise |
Vendored version of aantron/promise with melange support PR#80 | promise |
server-reason-react.belt |
Implementation of Belt for native API reference | melange.belt |
server-reason-react.js |
Implementation of Js library for native (unsafe/incomplete). Check the issue #110 for more details |
melange.js |
server-reason-react.fetch |
Stub of fetch with browser_ppx to compile in native | melange.fetch |
server-reason-react.webapi |
Stub version of Webapi library for native code compilation | melange-webapi |
server-reason-react.dom |
Stub version of Dom library for native code compilation | melange-dom |
The documentation site is generated with odoc and hosted on GitHub Pages.
The demo folder contains a bunch of demos under a server to showcases the usages of server-reason-react. Check the README for how to setup and run it.