We do a lot of mobile product development at Cantina, and a common question that’s asked both by our clients and by us at the beginning of new projects is: How should we approach building this?

With most mobile products, our clients want users on both major platforms - iOS and Android - to be able to use their application. Ideally, apps on both platforms should be at feature parity and available to users at the same time. In the past, Cantina has worked with clients launching new mobile products to target one platform first, then expand once the app gets market traction. But more and more, we’re seeing clients expect both platforms at launch.

React Native is not the first mobile app framework to promise write once, run anywhere. Xamarin, Cordova/PhoneGap and Ionic, among others, have been making that promise for years. At Cantina, we’ve researched them all, used many, and found that the end result often didn’t meet our expectations. The Newport Folk Festival app, a longtime Cantina client, is an good example. Developers built the original version of the app with PhoneGap. The following year, we rewrote it as two separate, native applications.

React Native is the first cross-platform framework that we believe delivers on the multi-platform promise without compromising user experience. We later rewrote the Newport Folk Festival app in React Native.

However, we still invest in and recommend native development in many projects. React Native is not a silver bullet, and it is not the right choice for many situations. Lately, a number of other tech companies have gone public with their experiences with React Native, both positive and negative. AirBnb recently shared their experience building with React Native, as well as the reasons they’re looking to move away from it.

I’d like to share some of the questions we like to ask to help us and our clients decide between native mobile development and React Native. I’m assuming here that you’ve already committed to building an app. The question now is how to deliver the best app experience, as fast as possible, with as little investment as possible.

Your App

The ideal scenario for a React Native project is a greenfield project for a user experience backed by a web API, that needs to be delivered quickly, and is being built by a team already well versed in web technologies. When the user experience becomes too complex, or the app requirements too great, or the team doesn’t already know JavaScript development, the trade-offs start to weigh in favor of a native application.

Are we building a new app, or are we building an extension to an existing app?

React Native strengths are most apparent when either starting a new project or completely rewriting an app. If you already have an app or apps and you’re considering integrating React Native into the existing system in order to build an additional feature, you’re introducing fragmentation in your project; you now have three platforms to support instead of two. The confusion for your team may not be worth the cost.

How much external communication does the app require, and over what mechanism?

React Native was born by adding a native-code bridging mechanism to the React framework for building web apps. It shines when building apps that are mainly interfaces for cloud services. If your app needs to communicate with other devices over Bluetooth, Near-Field Communication (NFC), Bluetooth Low Energy (BLE), or a direct WiFi connection, React Native may not be the best choice as it puts an additional layer between the app and the communication layer. Android and iOS each handle Bluetooth communication slightly differently, and those differences mean that debugging is easiest in a native app.

That said, the native bridge is getting better all the time, and a lot of work is being put in to BLE communication into React Native apps.

What does your app need to store locally on the device?

React Native is plenty capable of storing data locally on the device, but as requirements for local data storage grow, or if complicated data structures are needed, the app will hit a point where doing it in native code is easier. React Native can struggle with complex persistence models.

How much of the design of your app can be shared between platforms?

The power of React Native is sharing code between two platforms. One view layer, one business logic layer, two platforms. However, how much of the design experience can actually be shared between the two platforms? Is your app heavily inspired by Material Design, and as a result feels wrong on iOS, or does your style make a Samsung look and feel like an iPhone? What types of navigation are you looking to implement in your app? If you want a UI that feels completely at home on its device, React Native’s singular experience may not be the right choice.

What type of Mobile Devices does your app need to run on or work with?

Right now, React Native works on Android and iOS devices. But mobile products have many other systems available. Do you want to have a companion app for the Apple Watch or an Android Wear device? Could there be a Smart TV app? React Native does not support these platforms. When you start adding additional platforms, the “write once, run anywhere” promise immediately disappears, and you could start to consider other ways of code sharing.

Are there any complex audio, video or graphics requirements for your app?

When you’re doing complex audio, video, or graphics work, such as in a game, you need to squeeze as much performance from the limited mobile device hardware as you can. React Native adds additional complexity to your application; it runs in a JavaScript VM inside the app. If you need maximum speed, native should be your first choice.

This is a growing concern with applications that feature machine learning, augmented reality, or virtual reality.

Your Team and Company

The requirements of the app shouldn’t be the only thing driving your decision. Your mobile product team is just as important as the tech.

What technical talents does your team already have, and what technical talents would you like to grow in your team?

What areas of expertise does your team already have? If you have a team with experience in Objective-C/Swift, or Java/Kotlin, does it really make sense to put them on an entirely new platform and language, JavaScript?

Conversely, if you have an entire team of web developers fluent in JavaScript, and you need to ramp them up on mobile, React Native can be a great way to start doing that. However, you can only go so far on React Native without needing to write something in native code. At that point, you’ll either need someone with experience, or the time to ramp someone up on a mobile platform, to overcome that obstacle.

How important is stability, fragmentation, documentation, and availability of third party party code?

React Native is a JavaScript framework, and one of the great things about JavaScript is the availability of 3rd party open-source code to choose from, to help get past already solved problems. However, relying on too much 3rd party code can introduce problems and make your build fragile. Ask a developer about the left-pad fiasco for a worst-case scenario.

Additionally, React Native itself is still an evolving project, and the teams working on it regularly introduce breaking changes in to the available APIs. There is no stable “1.0” version of React Native yet. Your team needs to be able to keep up with the changes as they come, in order to keep building your application.

React Native is getting better each day, with major companies, hundreds of developers, and thousands of projects using and growing it with success. Developers’ satisfaction with it is often high as well. It’s a great choice for writing multi-platform applications. But it’s not perfect, and you need to be careful when choosing to use it.

At Cantina, we’re working with our clients every day to help them make the right choice for their project. We’d love to hear your experiences using React Native, and what criteria you use to decide.