Cover Photo by Kelly Sikkema on Unsplash
These blog posts assume that you are familiar with React and React Native. For simplicity, I will also use Expo.
I also assume that you already know the benefits of using ReasonML. If not I highly recommend checking ReasonML docs or old but still very relevant "Why ReasonML?".
Part 1: Expo + ReasonML setup
This is the first part of the blog post series about building a mobile app with the use of Expo and ReasonML. The main focus on in this part is on setting up the project and writing the first component in ReasonML.
Let's get started
In order to be able to use ReasonML in our Expo app, we will need to add BuckleScript (now known as ReScript). It is needed to compile the ReasonML/ReScript code to JavaScript.
We will also need React Native bindings. I will talk more about bindings in the upcoming blog post of this series. Bindings allow for a typed interface between JavaScript code and your code in ReasonML.
1. Create an Expo app
First, let's start with creating the Expo app (in case you do not have Expo installed check out the docs):
# Create a new project
expo init my-project
in the next step Expo will ask you what template to use:
I would recommend using the blank (Typescript) template from the Managed workflow.
2. Add ReasonML
Instructions on how to add Reason React Native to your current project can be followed here: https://reason-react-native.github.io/en/docs/install (under "Add Reason React Native to an existing project").
Or you can follow the steps below:
add the dependencies
As previously mentioned we will need BuckleScript, Reason React and Reason React Native bindings
yarn add bs-platform --dev
yarn add reason-react reason-react-native
create bsconfig.json
in the root of the project
bsconfig.json
is a configuration file used by ReScript (former BuckleScript)
{
"name": "my-reason-react-native-app",
"refmt": 3,
"reason": {
"react-jsx": 3
},
"package-specs": {
"module": "es6",
"in-source": true
},
"suffix": ".bs.js",
"sources": [
{
"dir": "src",
"subdirs": true
}
],
"bs-dependencies": ["reason-react", "reason-react-native"]
}
create src
directory and add App.re
into src
In App.re
we will create our first component in using ReasonML:
open ReactNative;
[@react.component]
let make = () => {
<View> <Text> {React.string("Hello from ReasonML!" ++ {j| 🎉|j})} </Text> </View>;
};
add scripts to package.json
Let's add three scripts that will allow us to build, clean and build in a watch mode our ReasonML code.
"re:build": "bsb -clean-world -make-world",
"re:watch": "bsb -clean-world -make-world -w",
"re:clean": "bsb -clean-world"
edit App.tsx
in the root of the project
Expo project comes with an initial App.tsx
we will edit it to use the App.re
from src
directory as our root component:
export { make as default } from './src/App.bs.js';
We import the App.bs.js
file as this is the file that gets created by ReScript compiler.
3. Run the app
In one terminal let's run the ReScript compiler in the watch mode:
yarn re:watch
In the other run the Expo app:
yarn start
You should see:
4. Summary
Adding the ability to write ReasonML isn't hard so give it a try and see for yourself what benefits it can bring to your project!
I created a small helper - Expo ReasonML Starter so there's no need to go through these steps every time you want to build a new app in Expo.
Edit:
In the end, I made it even easier to so you can start building your app with just one expo init command:
expo init -t expo-template-rescript
If you need more details or want to improve the template, here's the repo: https://github.com/mlventures/expo-template-rescript
What's coming next:
- building an actual app with ReasonML (making use of most common React Native components and API)
- writing bindings
- in case there's anything else you'd like to see in this series, please comment below or ping me on Twitter
Top comments (1)
Thank you for writing this 👏
I have decent RN knowledge but never used ReasonML. One thing that would definitely makes Expo + ReasonML interesting for me the possibility to target Desktop apps using something like outrunlabs.com/revery/ instead of Electron (which is considerably easy to do thanks to Expo team).
Is something like that possible easily without getting distracted from the actual app?