Building type-safe mobile apps with Expo and ReasonML (part 1)
Tags: reason, react, reactnative
Published: 2020-09-15 19:29:21


---
series: Building type-safe mobile apps with Expo and ReasonML
---

*<span>Cover Photo by <a href="https://unsplash.com/@kellysikkema?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Kelly Sikkema</a> on <a href="https://unsplash.com/s/photos/mobile?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>*

---


These blog posts assume that you are familiar with React and React Native. For simplicity, I will also use [Expo](https://docs.expo.io/).

I also assume that you already know the benefits of using ReasonML. If not I highly recommend checking [ReasonML docs](https://reasonml.github.io/docs/en/what-and-why#why-reason) or old but still very relevant ["Why ReasonML?"](https://medium.com/@johnhaley81/why-reasonml-part-1-8a975bbcf5f7).

# 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](https://rescript-lang.org/#why-the-rebrand)). 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](https://docs.expo.io/get-started/installation/)):

```sh
# Create a new project

expo init my-project
```

in the next step Expo will ask you what template to use:
 
![Expo project templates](https://dev-to-uploads.s3.amazonaws.com/i/yd46gu3979u7vyirn5tp.png)

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

```sh
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)

```json
{
  "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:

```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:

```js
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:

```sh
yarn re:watch
```


In the other run the Expo app:

```sh
yarn start
```

You should see:

![iPhone app](https://dev-to-uploads.s3.amazonaws.com/i/7n7y46pzmo9tjkj2x7xt.png)

## 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](https://github.com/mlventures/expo-reason-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:

```sh
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](https://twitter.com/matzatorski)