Reason & React-Native

K - Sep 11 '17 - - Dev Community

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 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.

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

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
Enter fullscreen mode Exit fullscreen mode

Next step is to install the Create-React-Native-App.

npm i create-react-native-app -g
Enter fullscreen mode Exit fullscreen mode

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

create-react-native-app my-awesome-app
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

For Android you can get it from Google Play

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:

open ReactNative;

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

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
Enter fullscreen mode Exit fullscreen mode

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

bs stands for BuckleScript, a back-end for the OCaml compiler that we are going to use. It can compile OCaml and Reason into JavaScript. Like Babel 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:

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

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Finally everything is in place.

Start the React-Native dev server with:

npm start
Enter fullscreen mode Exit fullscreen mode

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 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
Enter fullscreen mode Exit fullscreen mode

And then install the VSCode Reason plugin.

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 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%">
Enter fullscreen mode Exit fullscreen mode

to writing this:

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

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 that might help you.

Thanks to Ken Wheeler who wrote a React-Native app in Reason which I took as basis for this post.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .