During a few HackFridays we've experimented with React Native by building a voting app.

MuchVote, SuchRate by Donderlab (Source Code, Website, App Store, Google Play)

Here it is our take on React Native.

What is React Native

Instead of trying to accomplish the impossible "write once, run anywhere", React Native's promise is that you "Learn once, write anywhere", you can use the experience you have building great user interfaces from the web to mobile. But you will still need different code bases for each platform. You may have components that can be reused directly and others that are platform specific. There are many native APIs which are platform specific, you can have an idea by looking at the sidebar of components and APIs of the react native documentation page. And besides that the behaviour of your app for the same code will be in cases different depending on the platform.

React.JS abstracts the DOM so you can build your views and it will manage how to best reflect the changes to the DOM. It is declarative, and encourages highly modular programming. React Native takes the (magic of) code of React.JS and only switches the bridge between the React.JS and the DOM and instead renders to platform-specific native components. It doesn't have to stop at mobile, there's even an unofficial React Native implementation that renders to the desktop (Mac OSX) instead.

What makes it special from other attempts is the bridge that is asynchronous, batched and serialisable, that means that your application won't be waiting on javascript. Instead of running the javascript on a webview it is run on background thread on a instance of JavaScriptCore (native). You can also plugin native components that already exist and use React Native as an wrapper and use it for the UI/UX and layout of the app as you develop for the web.

First Impressions

To make life interesting we made this on linux environment and since we are going for something simple nearly 100% of the code is shared between Android and iOS. Besides this, the two member team (Délio and I) working on the React Native haven't worked on mobile previously and neither React.JS.

The React Native CLI init functionality is a godsend, it will scaffold you a project with basic structure, the XCode project and android Gradle project:

npm install -g react-native-cli
react-native init AwesomeProject

You are now ready to jump right into it. However, your first interaction with React Native will soon result in a red screen of death that you won't be able to ignore. At first these will be very cryptic but after much swearing, crawling stack overflow and reading the documentation you will realise that these errors and warnings are a blessing.

Your experience with React Native will depend on your development environment, on a Mac everything is easier and just works, most Facebook employees work on a Mac. Development on Linux and Windows is community driven. We have spent a significant effort on automating the development on Linux for android using npm scripts to setup the android virtual device and the android debug bridge.

  "scripts": {
    "avd:create": "android create avd -t 1 -n MuchVote -d 9 -b x86_64 -s 1440x2560",
    "avd:start": "emulator -avd MuchVote -gpu on -dpi-device 560 -scale ${SCALE:-0.25}",
    "adb:reverse": "adb reverse tcp:8081 tcp:8081",
    "android": "npm run adb:reverse && node node_modules/react-native/local-cli/cli.js run-android",
    "start": "npm run adb:reverse && node_modules/react-native/packager/packager.sh",
  }

There's a real and worrying fatigue element to developing on this environment: you will soon notice you have ton of terminals open, the amount of tooling and boilerplate associated, managing configurations, and so on. Nuclide a IDE from Facebook built on top of Atom addresses some of these issues, we haven't used it but it looks promising.

These last impressions are quite negative, you will need to be comfortable with an always changing environment that requires constant learning.

The fact that we're able to develop a native application in short period with no experience in mobile speaks volumes of the React Native framework. And that is able to deliver on its main promise of having web development knowledge translate into mobile development.

There's also much to be appreciated from the highly iterative process of development with some great tools and great packager, which greatly enhances the developer experience, it is clear that developer experience is an high priority. An example of this is the recent introduction of hot reloading.

Advantages

  • NATIVE
  • The bridge is asynchronous, batched and serialisable calls
  • It brings the declarative and highly modular programming of React.JS and a great layout and style implementation with flexbox and the box model
  • React.JS used in critical production products and also React Native (but less so) which implies high commitment from Facebook

Disadvantages

  • Bleeding edge
  • Not really hybrid, and is focused on iOS: you will find more bugs and less tooling for android.
  • Development environment limited for linux, better tooling and development experience on mac (forget windows)
  • Documentation that exists is good but is not extensive, you will often find yourself searching through github issues or stack overflow.
  • You will still need an experienced native developer for more complex applications to plugin native components and guide the JS developers on mismatches between expected behaviour (from the web) to native.

Resources

Here are some great resources to getting started with React Native: