Building Two Mobile Apps at Once… With Javascript

The only programming language that every full-stack developer must know is Javascript. A strong statement, I know. Let me justify it. Two and a half months ago I had never touched iOS or Android environments, and two weeks ago Edge released both Android and iOS versions of an app I wrote. How did I do it? Javascript and React Native.


React Native

React Native is a view library, built on top of Facebook’s React project, which uses native iOS and Android components to render components written in Javascript. It leverages React’s powerful properties, like compose-ability, clear component responsibilities, and reactive paradigm. But more importantly, it abstracts the implementation of built-in components.

Practically, this means I can write “<ScrollView>…</ScrollView>” and be assured it will (to a surprising degree) work on both Android and iOS. To me, this means I can write an Android app and an iOS app at the same time, with no experience in either platform.

The ScrollView component worked out-of-the-box with both iOS and Android!
Notice the UI cues for overscrolling are native

The Process

When I started at KPCB Edge, my experience with Javascript was building Backbone apps in the typical jQuery-heavy imperative style, usually by taking mock HTML created by our designer and adding interactions to it. But when I started on the Office Hours project, our designer-in-residence, Brian Tran, had already designed beautiful image mocks. So the first step was to take those images and render them with functional code. This first step, strangely, was the point of greatest friction for me.

In addition to learning how the iOS simulator worked, I had to think about UI in a radically new way. In React, the component hierarchy is not just a proxy for the layout, it’s also the logical structure of the project. Unlike an HTML document with embedded code (like an ERB template in Ruby), data must flow in a more structured way so React knows when and how to re-render. For example, the first component I implemented was the partner image in the home screen.

A first draft of the summary screen

Here’s the code to render the partner images:

And the code to render the whole summary screen:

Eventually each partner image needed to have some data property to indicate which image it should display, and it wasn’t immediately clear which component should be in charge of fetching that data from the server and then passing it through to each of the three image components. This blending of layout with logic also means it can be difficult to get a designer onboarded to contribute to the project. Brian already knew some Javascript, so the process was straightforward, but the key insight was the same for both of us: an interface built in React is architected and designed simultaneously.

Once the iOS version was working and submitted to the App Store for review, I began work on the Android version. Most of the components I had written still worked! There were a couple cases of components which had more general cousins that I had to replace (for instance, the <NavigatorIOS> component had to be switched out with the <Navigator> component). The relative immaturity of the Android implementation meant inconsistencies in styling and component APIs between platforms. But there were workarounds in both cases. For instance, the swiping carousel component I had used on iOS didn’t work on Android, so I replaced it with simple next and back buttons.

All said, porting to Android took 10 business days from first draft to app submission, and the code reuse between the two platforms was just about 90%.

Conclusion

The landscape for mobile development is fundamentally different with React Native. For most applications, there will no longer be an incentive to learn one of Android or iOS when learning Javascript gives you the ability to code for the server (node.js), the browser (React), mobile (React Native), and even the desktop (React Desktop). For the first time, it’s practical to be a truly full-stack developer by knowing just one language and a few frameworks. Even Javascript itself is quickly evolving into a modern, functional language. As React Native matures, we’ll begin to see more perfect feature-parity with native mobile development. The barriers to writing an app will dissolve for anyone who knows javascript.

Thanks for the help!

A shout-out to two organizations which made the app possible: Smooch and the React Native community.

Smooch is the chat solution we used for Office Hours V1, and when we started the React Native version of Office Hours, Smooch had no React Native library, but they were responsive to our needs and built a library with both Android and iOS bindings.

React Native is a young project — it was open-sourced 9 months ago — so there are rough edges, especially on Android. But the community, especially on Github, was indispensable to us. I can’t tell you how many times I discovered a bug only to realize it had been discovered by someone else 2 days ago and there was already a pull request to fix it. The community builds fast, communicates clearly and politely, and releases often.

This post was written by Andrew Taber, our Developer in Residence. Learn more about our residencies here.