At Manas we organise internal hackathons on a monthly basis, with the goal to explore new technologies, languages, frameworks, paradigms, or whatever we want to play with; thus both satisfying our need to be constantly learning, and evaluating the tools that we will use for the projects to come. We have tried ReactJS, Clojurescript, Phoenix, LISP, and, most recently, React Native. For every hackathon, the members who participated share with the rest of the team their findings and experience; this time, we decided to share it publicly here on the blog.

The context

It is worth mentioning that all of us who were on this hackathon are primarily web developers, rather than mobile developers, and the browser is a much more familiar environment than Android or iOS. We all did have experience with Javascript, and ReactJS to a minor extent. Also, we are all Mac users, so the development was done on OSX and not Linux. We tested React Native version 0.23.

The what

In one sentence, and from their homepage, React Native is a framework for building native apps using React.

ReactJS is a Javascript framework developed by Facebook, that brings a different programming model for building JS views. It is strongly based on componentisation, where each component is fundamentally a function that returns an HTML fragment from a model. Whenever there is a change in the model, the framework re-evaluates the view, calculates the diff with the current one using a virtual DOM, and enqueues the change operations on the actual DOM.

React Native uses the same approach, but instead of outputting HTML, it yields Android or iOS native components. The development is done in javascript as well, where each component yields an HTML-esque output, but using React Native wrappers for the actual native components instead of HTML nodes. Skimming through the source code of their tutorial should give you a good initial idea of how the framework works.

The setup

Though React Native requires a full Android and iOS development setup, plus all the actual React Native libraries, the setup is surprisingly easy. Downloading all prerequisites, especially the Android SDK and XCode, might take a few hours if you hadn’t had downloaded them previously, but the configuration is pretty straightforward and powered by npm.

The experience

We first went through the tutorial that covers the basics, and soon went on to implement an app of our own; we decided to work on a client app for reporting time to

As we worked on the apps, we found that the same philosophy used for developing web apps using React could be brought to the mobile environment with almost no friction.

The basic set of controls are easy to use and understand. Basic events, such as “clicks”, are managed via Touchable wrappers to standard controls. Styling inside Javascript did not feel out of place, and the properties felt familiar; also, the Flexbox layout system follows the same rules as the CSS one.

Even though React Native does not attempt to be a write-once use-everywhere solution, and encourages you to write different interfaces for iOS and Android, sharing only the common business logic, we found that for a simple application we could use exactly the same codebase, since the React Native wrappers over the basic components are the same for both platforms.

Running and debugging the code was surprisingly easy. Simple command-line commands allow you to start either the iOS or Android version in an emulator, and once the app is running, it just needs to connect to the local dev server to download the new JS bundle to be executed, thus greatly speeding up the compile/run cycle. Debugging is done by attaching the app to a Chrome page, and using its own - already familiar - developer tools for going through the javascript code. Running the app on an Android phone was also easy to do, and once initially set up via USB, switching to Wifi to update the JS bundle was painless, always allowing for the same reloading and debugging practices as with the emulator.

The bad and the ugly

React Native still hasn’t reached its 1.0 milestone, and we did stumble upon a few killer bugs. Attaching the debugger to an Android emulator changed the behaviour of the Fetch API, requiring an extra user interaction to actually return the result of a request, something that took us a few hours to figure out; fortunately, this issue has been already identified and solved in the upcoming version. Also, we could not run the app on the iOS emulator or deploy to an iPhone unless Chrome debugging was running, something that has also been reported by others. Documentation on some modules is scarce (see the Flexbox polyfill docs for instance), but being open source, we could always fall back to the source code to figure things out; so lack of docs was not a showstopper at any point.

The missing pieces

Being a one-day event, we missed several features of the framework that we would have liked to evaluate, such as bindings to native code, local storage, notifications, background operations and access to specific phone services such as geolocation.

We would also have liked to try React Native in combination with another framework, such as Redux, in the context of a larger app - but this can be the goal of a future hackathon.

The conclusion

Clearly a thumbs-up for React Native. We had already fell for the development model introduced by React, and being able to carry that model almost directly the the mobile environment is immensely powerful, especially taking into consideration the implementation of applications across mobile browsers, Android and iOS apps.

Use in production still feels a bit risky at this point, considering some of the bugs we faced, but we cannot rule out the possibility that with some additional time we could have worked around them.

All in all, React Native looks like a fantastic tool for implementing mobile apps, especially for developers coming from the web world.

You can check out the code of the app we implemented here.