On 26 March 2015, during the F8 conference, Facebook published the iOS version of React Native on GitHub under a BSD licence; the Android version is announced as forthcoming. The project had already been previewed at React.js Conf in January, but the code only becomes public now.

Context

In 2015 mobile development follows two separate paths. iOS asks for Objective-C, Xcode and the UIKit APIs; Android asks for Java, the Android SDK and its own View hierarchy. The two platforms have different release cycles, conventions and debugging tools. Keeping two codebases for the same app means double the work and functional divergences that are hard to avoid.

Until now the most common alternative is the hybrid approach: Apache Cordova and PhoneGap wrap an app written in HTML, CSS and JavaScript inside a WebView, that is, a browser without an address bar. The gain is code sharing; the cost is that the interface does not use the operating system’s controls, and on less powerful devices the difference in scrolling and animation shows.

Architecture

React Native brings the React model — already familiar from the web — to mobile development, with a difference in the last step. A component written in JavaScript does not end up in DOM elements but in native objects of the platform. A <View> becomes a UIView on iOS; a <Text> a native text label; a <ScrollView> scrolling handled by the operating system. The code stays declarative and in a single language, but what appears on screen are the system widgets, not a page inside a browser.

Underneath there are three threads running in parallel. The JavaScript thread runs the app logic inside an engine — on iOS the same JavaScriptCore as Safari. A layout thread computes element sizes and positions with the Flexbox implementation bundled in the project. The main thread, the one driving the interface, applies the changes to the native objects and handles input events.

These worlds do not share memory. They talk to each other through a component called the bridge. When the JavaScript logic decides that the interface should change, it does not touch the UIView objects directly: it produces a description of the changes, the bridge serialises it and passes it to the native side, which applies it. The path runs both ways: a touch on the screen is caught on the native side, serialised, and delivered to the JavaScript thread as an event.

The critical point

The bridge’s properties decide the behaviour of the whole system. They are worth a close look: they explain the architecture’s strengths and its limits.

Communication is asynchronous. Neither side waits for a reply from the other. The rendering thread therefore cannot be blocked by a long JavaScript computation: in the worst case the interface keeps responding to input while the logic falls behind, rather than freezing outright. For perceived responsiveness this is an advantage, at the price of a rule: no operation may cross the boundary and expect an immediate result.

Messages are serialised — today in JSON — and gathered into batches. Individual operations do not leave one at a time: they pile up and are sent as a group, so there are fewer crossings over the bridge. Each crossing has a cost: serialise, transmit, deserialise. As long as the data crossing the boundary stays small, the cost is negligible; when it grows — for instance scrolling a very long list that produces many events per second — it becomes the factor that slows performance.

The choice is coherent: keeping the two worlds separate lets you write the logic in JavaScript without rewriting the rendering engine, and use native controls without wrapping them in a browser. The price is that the boundary must be treated as a scarce resource, not as an ordinary function call.

Implications

On the development side the feedback loop changes. A change to the JavaScript code reloads into the running app without recompiling the native binary and, often, without losing the screen’s state. On a classic iOS project a change requires a compilation that on large codebases is measured in minutes; here the result is almost immediate.

On the shared-code side, the business logic, state management and network calls can hold for both platforms, while each platform’s specific parts stay accessible. When a system capability that React Native does not expose is needed, a native module is written in Objective-C — and, once Android arrives, in Java — and made callable from JavaScript through the same bridge.

Opening the code does not happen on its own. In the same F8 days Facebook published ComponentKit for the iOS interface, Fresco as an image library for Android, and the Year Class and Connection Class utilities for profiling on Android. React Native is the most visible part of a broader release of mobile tools.

Limits

As of today, 15 April 2015, the public release covers iOS only. The Android version is given as imminent but is not here, so code sharing between the two platforms cannot yet be verified in practice. The project is young: the exposed components are few, and any native control not yet covered has to be written by hand.

The bridge remains the thing to keep an eye on. Interfaces with little data in transit gain the most; those that push large volumes of events across the boundary — scroll-driven animations, very long lists — should be measured case by case, because the serialisation cost cannot be removed by design. It will be use on real apps, together with the arrival of Android, that shows how far this architecture holds outside the demos.


https://code.facebook.com/posts/1014532261909640/f8-big-technology-bets-and-open-source-announcements/ https://github.com/facebook/react-native https://facebook.github.io/react-native/ https://techcrunch.com/2015/03/26/facebook-open-sources-react-native/ https://www.noze.it/en/insights/react-native-open-source/

Cover image: Mark Zuckerberg, in a dark t-shirt, speaks on the lit stage of Facebook’s F8 2015 conference in front of a large screen — photo by Maurizio Pesce, CC BY 2.0 — https://commons.wikimedia.org/wiki/File:Mark_Zuckerberg_on_stage_at_Facebook’s_F8_Developers_Conference_2015_(16934644455).jpg