Here is a guide on how to get started with React Native and ReasonML. For the purpose of this blog post I assume that you are already familiar with React Native and partially with ReasonML. If you are not set with ReasonML yet, check out the docs.
Let’s start by installing React Native CLI:
1 |
npm i -g react-native-cli |
Now we can initialise a new React Native project, just like we would do with every React Native app:
1 |
react-native init MyReasonApp |
Adding the “Reason bits”
We will need 3 packages:
bs-platform
— compiles ReasonML/OCaml to clean, readable and performant JavaScript codereason-react
— Reason bindings for ReactJSbs-react-native
— BuckleScript bindings for React Native
Let’s add them to our project:
1 |
npm i -P bs-platform reason-react bs-react-native |
Now we need to create a bsconfig.json
, which is a BuckleScript’s configuration file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ "name": "my-reason-app", "bsc-flags": ["-bs-no-version-header", "-bs-super-errors"], "refmt": 3, "bs-dependencies": ["reason-react", "bs-react-native"], "reason": { "react-jsx": 2 }, "package-specs": { "module": "commonjs", "in-source": true }, "sources": [ { "dir": "src", "subdirs": true } ] } |
Let’s stop for a minute in here. There are a few bits that are different from the usual setup.
First is "subdirs": true
, makes BuckleScript aware that it should check subdirectories for code that should be compiled.
The other one is "in-source": true
, this one is pretty handy, generates output alongside source files (by default they are output to lib/js
). This is pretty useful when we reference .js
files or assets files. Without it, to import an image you will reference it like:
1 2 3 4 5 6 |
<Image style=Styles.icon source=( Required(Packager.require("../../../assets/right.png")) ) /> |
with the option "in-source": true
, it’s going to look like:
1 2 3 4 |
<Image style=Styles.icon source=(Required(Packager.require(“./assets/right.png”))) /> |
I prefer the latter, hence I enable the option.
Let’s also add a few scripts to the package.json
that we will use later to compile our code:
1 2 3 4 5 6 7 |
"scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "test": "jest", "build": "bsb -make-world", "watch": "bsb -make-world -w", "clean": "bsb -clean-world" }, |
ReasonML in React Native
We are done with the configuration, to recap, we added three packages: bs-platform
, reason-react
and bs-react-native
. Then we added BuckleScript’s config file bsconfig.json
, that’s all! 🎉
Let’s write some Reason now!
As we previously defined in the bsconfig.json
we will keep all of our ReasonML code in the src
directory. In the newly created src
directory (in the root of our project), let’s add App.re
, it could look something like:
I also removed the App.js
from the root of the project (that’s the file that is generated by React Native CLI).
Last thing we need to do is import our compiled App
into the index.js
:
Finally we can compile our code by running:
1 |
npm run watch |
This will watch for any changes you do to your Reason code and compile (if there are no errors).
Now let’s start the React Native app:
1 |
react-native run-ios |
You should see:

Happy hacking! 🎉
Here is the link to the repo with the above setup: https://github.com/knowbody/ReasonReactNativeApp
Thanks to lanqy, this blog post is also available in Chinese: https://lanqy.xyz/2018/05/30/getting-started-with-reasonml-and-react-native/