A short Story about React Native

React Native is probably the hottest trend in Mobile Development since the release of Swift in 2014.

The concept is pretty simple: it lets you build native apps in Javascript for iOS and Android (among other platforms). It's the most promising project for solving the complexity of mobile development (different codebases for every OS, fragmentation, iteration speed, imperative programming).

Let's see how the story began:

In a speech given by Christophe Chedeau at QCon NY 2015 you can discover a lot of the reasons for the creation of React Native.

Mobile Web Limitations

Christopher was working in the photo album team of Facebook in 2013. At that point, he was new in the company and the challenge was to transform Facebook into mobile first product(s).

The original approach was to create a mobile native container filled with WebView that were already existing on Facebook servers.

However, problems started to appear pretty quickly: the user experience was bad because of the lack of mobile-specific API on mobile browser appeared to be a real technical limitation. The particularly lacking features were:

  1. A keyboard API to detect when the keyboard was there and when not being able to adapt the view (and the focus).
  2. A touch handling and gesture API which reacts faster than onClick (which has a ~300ms delay) and provides richer events (for instance in order to handle multi-finger gestures).
  3. A real logic for image management: you cannot query the browser cache directly to see if the image already loaded or not.

If you're a native mobile developer, you've just realized that these are problems we never have to face: the Keyboard API is "for free" (Android, iOS), the touch events are very detailed (Android, iOS) and for the image management I use Fresco or Picasso on Android and I guess that Nuke does the work on iOS (I have never used it though).

But being a native mobile developer has 3 major drawbacks:

  1. You iterate so slowly! The necessary process for prototyping an app on iOS and letting it be tested by your manager:
    1. Code.
    2. Build binary.
    3. Create provisioning profiles and distribution certificates.
    4. Upload to App Store.
    5. Have it reviewed by the algo of Apple (~1 hour).
    6. Create the Testflight (add all the users that you want to show your app to).
    7. Download the App
    8. Install the App.
    9. Test
  2. You code in an imperative way and do not benefit from the "philosophy" of React:
    • The more the app is complex the less you're confident in your changes.
    • You have tons of side-effects that you do not always understand.
    • You have to manage the breaking changes of the native SDKs (in particular on iOS).
  3. You need as many code bases as the number of platforms you support (generally 2 (iOS and Android) but could be 3 (because of Windows Phone)). That's a management pain, much higher development costs and a slower iteration process.

A long way to the solution

So, Mark Zuckerberg summarized these problems in one sentence at Techcrunch Disturb SF 2012:

Our Biggest Mistake Was Betting Too Much On HTML5.

From that very moment, it was pretty clear that the leaders of the industry had to find other options to develop great mobile user experiences.

As Christopher Chedeau explained in his talk, a Facebook guy named "Jordan" (Jordan Walke who did (among many other things) the decoupling of ReactJS from the Facebook Stack for Instagram (Tom Occhino, Introducing React Native at 8.00)) managed to generate UILabel in iOS from Javascript.

The hackathon

From that, Christopher, Jordan, Ashwin Bharambe and Lin He took the decision to perfect this prototype and tried to get something working in 2 days.

At the end of these 2 days, they were able to generate native UI Elements from a JS Thread running directly on the end-device. The most important part for them was: they just started to tackle the iteration slowness problem!

A press on Command+A to refresh the view!

Further developments and research

After this hackathon there were two types of reactions in the team: those who saw potential but didn't want to commit yet (Christopher and Jordan) and the others who saw potential and wanted to use this prototype on real Facebook Apps.

After 3 months of intense development, the progresses made were too small and the team was really far from a production-ready app because they spent a lot more time building what we today call React Native and couldn't focus on the product itself.

That made "click" in the head of Jordan and Christopher who took the decision to create and dedicate a full team for building this technology.

Release

React Native was released for the React.js Conf 2015 and presented by Tom Occhino in a very interesting keynote which reviewed the past of React starting from XHP, going through ReactJS (revolutionizing) principles and how they will be applied in React Native.

How does React Native work?

As explained before, the main idea is to use the best of both worlds: the tremendous capacities of native SDKs and the speed of development of Javascript.

An external Javascript Thread interprets the JS written Code (React-Like) and publishes events to the Main Thread which refreshes the UI and calls native code.

There are two keys to make the development process fast and more bug-free:

React principles

ReactJS revolutionized the way JS frameworks are built by introducing the concept of VirtualDOM.

Screen-Shot-2018-01-14-at-9.14.32-PM

VirtualDOM is a major step in the implementation of DECLARATIVE programming.

Instead of trying to write down why you want to code for the web in a declarative way, I prefer to let the genial Mattias Petter Johansson
explain that!

And now, why couldn't we apply the principles of VirtualDOM on other imperative APIs?

That's exactly what React Native does:

  1. Compare current state with rendered state (the state that the screen is representing).
  2. Push the differences by using the imperative API via the Bridge (see below)
  3. Redo at a maximum rate of ~60 times per second (batch all the incoming events in batches) not to have unnecessary updates.

The Bridge

The Bridge of React Native is a wonderful piece of software engineering with 3 specificities:

  • Asynchronous: it works with good old callbacks. It means that the JS thread continues to execute some logic even if the main thread is slower than it should.

  • Batched: A human eye just needs 60 fps to see smoothly, why would you need to send more than 60 updates per seconds to the Main Thread? The Bridge collects the differences between the states and sends the delta to the Main Thread for every frame.

Screen-Shot-2018-01-14-at-9.07.54-PM

  • Serializable: All transactions can be serialized not to have to reference native objects which could be garbage collected (that could lead to memory leaks).
    From the developer perspective it also means that you can record everything and just replay it.
    From a testing perspective it allows to separate the native tests from the Javacript tests. You test your JS and mock the native code; you test your native code and mock the JS part.

For more technical informations on how React Native works, have a look here.

Does it solve anything?

At correcting my article, my dad made a very good observation: I probably described the technical aspect in a relatively precise way but does it change something?, has it become easier and faster to develop good apps for mobile?

Technically

I enumerated 3 majors issues with Mobile Development before React Native:

  1. Iteration Time
  2. Imperative Programming
  3. Codebase Differences

That's a HOMERUN for Facebook, these 3 issues are wonderfully well tackled: I can add a button in the deepest view of my hierachy with no side-effect (problem 2.) on both Android and iOS (problem 3.) and release it on Expo in one command so that my manager receive the release over the air (problem 1.)!

My experience

The following paragraph is a summary of my one year experience with React and React Native: it is not necessarily objective and you have to know that I'm a former Android Developer who switched to Full Stack Development to build my startup.

My personal answer to "has it become easier and faster to develop good apps for mobile?" is actually MAYBE.

On one side, yes you kick off with Expo an app and code a clone of every app on the market in 48 hours. Yes it gives the opportunity to JS developers to enlarge their playground. Yes you can reduce your development costs. Yes developers are less frustrated because they have this instant reload and more tools.

But the path to the perfect mobile development platform is still very long: no, you do not have access to all the NodeJS libraries because some essential parts are missing (e.g. zlib). No, the packager doesn’t work as well as Gradle on Android nor the XCode compiler (the number of time where it crashes because you add a dependency is damn high). No the navigation problem hasn’t been cleared, it’s still cryptic and figuring out which library to use and how it works will cost you hours. No writing Redux (or any state library) boilerplate is not something pleasant even if it reduces side-effects. No managing the keyboard on both Android and iOS (with many screen-sizes) is neither intuitive nor easy.

But YES: a big organization took the decision to change things and forces all actors to innovate and that’s just great! Thanks Facebook!

Extension to other OS

As you might have notice, the principles of React Native can apply on EVERY platform. It means that you can write very similar code on every platform (you just have to respect the look and feel of every platform).

That's even the claim of React Native:

Learn Once. Run Everywhere.

Facebook released ReactNative for Android in September 2015 but some cool guys created React Native for other platforms (that's why we all love Open Source!):

Actually by rewriting the connectors between the bridge and the imperative API, you can use React Native on every possible platform!

Way to stability

At the time of writing, React Native is in version 0.52 and has a one month release cycle (new minor version every month). There is a lot of companies who built their products at least partially with React Native: Airbnb (see how), Instagram (see how) and of course JobNinja (with a codeshare between iOS and Android of 99%).

The community pushes it like very few projects on the open source scene:

  • 13th most starred project on Github
  • > 12k commits by > 1.5k contributors
  • 67 active Meetup groups all over the world dedicated to this technology.
    (to get the stat: load the whole list here and type $$('.groupCard--title h3').map((e)=> String(e.innerHTML).replace(/^\s+|\s+$/g, '')).filter((e)=> e.indexOf('React Native')> -1) in Chrome console... #scriptKid).
  • Tons of stories on Medium (I didn't find a hack to count them)

Licence issue

There was a big mismatch with React and React Native licenses: the reason is that Facebook found a (to me relatively elegant) way to counter patent trolls: you are free to use, modify or sell the code and its applications as long as you do not sue Facebook for Patent Infringement.

It made a bit of noise because React and React Native products are relatively wide used technologies but Facebook cleared the question by writing a pretty straight-forward FAQ. I also share the view of Christopher Chedeau who explains that a fair trade-off between open-source and legal concerns has been found.

Conclusion

React Native is a very exiting project and improves mobile development tremendously. Projects like Expo make the creation of a native app almost as easy as a website and that's very good news for the industry (iterate faster means improving conversion faster means more money).

I would conclude with a sentence of Adam Terlson that I met in Munich React Native Meetup:

React Native is, to me, the only way to create a content-based app efficiently.