Reason & React-Native
Tags: reason, coding, mobile
Published: 2017-09-11 07:10:32

---
title: Reason & React-Native
published: true
description: How to get up and running with Reason and React-Native
cover_image: https://thepracticaldev.s3.amazonaws.com/i/b74xm48ea1me82l89pyb.jpg
tags: reason, coding, mobile
---

_Edit (15.12.2017)_

There is now an easier way: 

https://github.com/react-community/reason-react-native-scripts

---

After my [last post about Reason](https://dev.to/kayis/a-reason-to-code) it took me some time to get at it again. Learning a new language takes time. You have to get the new syntax, the semantics and the tooling. I'm more of a practical learner, even tho' I like it to read about new tech for days and days, I know I don't really get stuff till I tried it myself and things are always different from how the creators tell you. 

Anyway, a few days ago I read about people trying to get Reason to work with React-Native and since React-Native is my thing at the moment, I wanted to try this out.

# What

I will tell you how to get up and running with React-Native and Reason. I will use Create-React-Native-App, because using React-Native directly is a bit of a hassle. So no Mac or 75 TB Android SDK required!

Requirements: __Linux and an Android or iOS device.__

This should also work with MacOS.

# How

First install the [Node Version Manager](https://github.com/creationix/nvm).

    wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.4/install.sh | bash

Then use it to install Node.js 7 _(Node 8 comes with npm 5, which doesn't work with create-react-native-app)_

    nvm install 7

Next step is to install the [Create-React-Native-App](https://github.com/react-community/create-react-native-app).

    npm i create-react-native-app -g

And use it to create... a React-Native app :D

    create-react-native-app my-awesome-app

__Some problems that could occur:__

`react-native-scripts` is missing, install it:

   `npm i react-native-scripts -D`

The process that listens for file changes needs some additional configuration, so it can _WATCH ALL THE FILES!_ 

This works till you reboot your system:

    sudo sysctl -w fs.inotify.max_user_instances=1024
    sudo sysctl -w fs.inotify.max_user_watches=12288

Now we have a regular JavaScript based React-Native app, we can start it with `npm start` and get a QR-code that we need to scan somehow.

We use our mobile device to install the __Expo client__.

For __iOS__ you can get it from the [App Store](https://itunes.apple.com/app/apple-store/id982107779)

For __Android__ you can get it from [Google Play](https://play.google.com/store/apps/details?id=host.exp.exponent)


The Expo client lets you scan the QR-code and will open the app created before.

This is all fine and well, but we are here for a _Reason_!

Lets add some Reason code to our project.

I prefer to put my app-code into a `modules` folder. So create one inside your `my-awesome-app` directory and then put an `app.re` in it!

The `my-awesome-app/modules/app.re` should have this content:

```reason
open ReactNative;

let app = () => 
  <View style=Style.(style([flex(1.), justifyContent(`center), alignItems(`center)]))>
    <Text value="Reason is awesome!" />
  </View>;
```

A simple function that returns some elements, nothing fancy.

But our app doesn't do anything with it right now, so we need to setup a tool chain for the build.

For this we need to add a few `devDependencies` to our project.

    npm i bs-platform reason-react bs-react-native -D

The OCaml compiler is compiled when installing this, which can take some time.

`bs` stands for [BuckleScript](https://bucklescript.github.io/bucklescript/Manual.html), a back-end for the OCaml compiler that we are going to use. It can compile OCaml and Reason into JavaScript. Like [Babel](https://babeljs.io) can compile the fancy ES2015/16/17 features into old-school JavaScript.

`bs-platform` requires a `bsconfig.json` in your `my-awesome-app` directory with some configuration to get running:

```json
{
  "name": "my-awesome-app",
  "reason": {
    "react-jsx": 2
  },
  "bsc-flags": ["-bs-super-errors"],
  "bs-dependencies": ["bs-react-native", "reason-react"],
  "sources": [{
    "dir": "modules"
  }]
}
```

Most important for us is the `dir` and the `name`.

We also need to add some `scripts` to the `package.json`.

    "build": "bsb -make-world -clean-world",
    "watch": "bsb -make-world -clean-world -w"

Since we installed `bs-platform` as a `devDependency` the `bsb` command will be available for these scripts.

We can now compile the `app.re` into an `app.js` by running 

    npm run build

You will find it at `my-awesome-app/lib/js/app.js`

Create-React-Native-App expects an `App.js` in your `my-awesome-app` directory that exports a React component as `default`, but our component is neither in the right file nor a default export. So we need to use the `App.js` to connect the Reason world with the JavaScript world.

Open up `my-awesome-app/App.js` and replace its content with this:

    import {app} from "./lib/js/modules/app";
    export default app;

Finally everything is in place.

Start the React-Native dev server with:

    npm start

Scan the provided QR-code with your mobile device and the Expo client and it should show you "Reason is awesome!"

Later you can use `npm run watch` instead of `npm run build` while running `npm start` so everything is compiled when you change something.

# Bonus

If you want to use all the nice features of Reason while developing, I recommend using the [Reason CLI](https://github.com/reasonml/reason-cli) with Visual Studio Code.

On Linux, install the CLI via npm

    npm install -g https://github.com/reasonml/reason-cli/archive/beta-v-1.13.6-bin-linux.tar.gz

And then install the [VSCode Reason plugin](https://marketplace.visualstudio.com/items?itemName=freebroccolo.reasonml). 

To get the nice auto-format with refmt you need to add `"reason.formatOnSave": true` to your VSCode configuration.
 
## Wrap Up

So getting started with Reason and React-Native isn't too hard I think. The dev-story for Linux feels a bit more clunky than on MacOS and overall React-Native is much slower on Linux than on MacOS, but that's a React-Native or maybe even a Create-React-Native-App issue.

What's missing, and expected to be missing in such a young language, are binding and/or libraries. I use [glamorous-native](https://github.com/robinpowered/glamorous-native) for my styles in React-Native and it really feels like a big step back to go from writing something like:

    <View backgroundColor="red" width="100%">

to writing this:

    <View style=Style.(style([backgroundColor("red"), widthPct(100.)]))>

Styling is the bread and butter of a front-end dev, so I don't know if I can take it, haha, but the autocomplete is certainly nice.

For such a very young project I think it's still a phenomenal achievement and worth a try.

Also, if you need some _visual_ help in setting up React-Native, I also made a video course on [Skillshare](http://skl.sh/2tRgwpE) that might help you.

Thanks to [Ken Wheeler](https://twitter.com/ken_wheeler) who wrote a [React-Native app in Reason](https://github.com/FormidableLabs/seattlejsconf-app) which I took as basis for this post.