Choosing a React Native Stack That Doesn’t Suck.

Written by pushplaybang | Published 2019/02/23
Tech Story Tags: react-native | mobile-app-development | javascript | react | react-native-stack

TLDRvia the TL;DR App

What to use, and avoid, if you’d like to “learn once”, and not suck everywhere.

The promise of React Native is “learn Once, write everywhere”. Moreover, a large part of the appeal is code reuse and the possibility of leveraging a burgeoning ecosystem to increase our velocity of development and decrease our cost of maintainability. If React Native can’t achieve that, without compromising the user experience, It’s not worth the trouble.

Good First Impressions

Diving into React Native for the first time, I certainly had the sense that this “isn’t your dads hybrid mobile dev experience”, and got tremendously excited considering what we could do, leveraging the teams existing JS knowledge. The thing is, it doesn’t stay that easy when you venture beyond the trivial getting started apps out there.

An Easy Access Hatch

There’s a subtle, but critical difference from the promise of previous hybrid technology, in that React Native is striving to provide a cross-platform interface to the native world, through javascript, and therein lies the rub. Relying too much on javascript for core functionality in your app, instead of leveraging the native capabilities of your target platforms, will lead you down a dark road of limited performance and diminished experiential quality.

A key question you should be asking, when starting a React Native project, is “will this actually improve or simplify the dev experience.”

Comparing it the Native Development

In all honesty, many of the hard bits about native development, are still the hard bits when it comes to using React Native. For many web developers, the allure of using JS everywhere is strong, but in my experience over the last year, it’s not learning Swift and Kotlin (or java if you must) for native development, but rather the native ecosystem, provisioning, build systems, dependency management, deployment to the app stores, performance profiling etc. A key question you should be asking, when starting a project with React Native, is “will this actually improve or simplify the dev experience while matching the user expectations”.

The Big Choices

There are a couple of critical cross-cutting concerns that will affect the user experience no matter the app, the ones we found to be the biggest decision were the following.

Routing

There has been a tremendous rise in the popularity of react navigation, a JS solution to routing in React Native. I, I’m sure like many, felt like it made sense at first, and comfortable with the fact that its a JS solution. I was happy with our choice until we found a simple slide animation couldn’t run without stuttering on a flagship device, in a simple text-based demo app. Now having done extensive research, there are ways to improve this, but as I will mention later, I don’t think we should have to work this hard for it, especially before we’ve even considered what else might be fighting for precious scarce resources on a device.

Enter Wix React Native Navigation v2. I cannot claim that moving to this solution was easy, the setup was arduous at best, and the documentation needs a lot of help. That said, once we got this all wired up, navigation is now smooth and fluid, and as a side benefit, our code is neater and far easier to reason about.

Backend

There are a few promising choices out there beyond rolling your own, and this will completely depend on your needs. For us, we are in most often building cross-platform web and mobile and beyond auth and push-notifications, more recently have had needs for cloud-based services such as media encoding, graph-data, etc. Having used GCP (and Firebase), Azure and AWS in the past, I initially leaned towards AWS, until I found the Firebase React Native project.

While all of these services are great, they all have their strengths and weaknesses. None of them provides a first-party native solution for React Native. Firebase has also been a win in terms of productivity, over the previous implementation I’ve done with AWS with a much nicer backend. That said, I was disappointed to discover only JS support for cloud functions for instance. t

Ultimately again, the deciding factor for us was being able to install the native SDK’s, which provided some additional benefits discussed in detail in their documentation as well as moving this off the JS thread.

UI Library

This seems to be an open area with React Native in General. There are a lot of libraries, some better than others, some more flexible, but ultimately I’ve been disappointed with each that we used. From react-native-elements, to native-base, react-native-paper, none seems full ready when it comes to building a production app.

As much as there is no clear winner in this area as an overall library, there are a number of singular components that are tremendously useful, that we use again and again:

Smaller simpler libraries seem to be a better choice as more complete libraries like React Native Paper, though promising, ultimately will require you to fork the library if you want the kind of customisation you’d expect for a production-ready app.

Check our awesome react native UI for an extensive list of projects.

State Management & Persistence

This is one area where I’m still strongly married to redux, and redux-sagas. Both help separate managing state from managing the UI and we use this across web and mobile.

But for native apps, a key difference is offline capabilities, without which you’re really just putting a web experience on the device, rather than developing a connected mobile experience. While redux-offline is a very popular choice, we’ve chosen redux-persist, which is little more bare bones, and paired it with RealmDB.

While you have a number of options with regards to persistence, whether that's just AsymcStorage, realm, or something like the new but impressive WatermelonDB, this will need to be a careful consideration in the context of your backend and front end architecture.

Firebase-react-native also handles some of this on its own in our case so redux-persist seems to be enough for us, though depending on your other choices, your affinity for redux, and how much parity you maintain with your web front-end should be considerations.

Disclaimer

There's a large part of this argument, that revolves around choosing native first. There are great JS libraries out there, and I’m well aware that there are many optimisations that can be made. Having personally implemented gesture driven 60FPS animations in Cordova years ago, I can attest to what’s possible. That said, we just shouldn’t have to work that hard, for something the native platform can give us.

Secondly, bad code is bad code, no matter the language or platform, simply using these libraries, or even switching to full native isn’t a silver bullet, especially given the unforgiving nature or mobile dev.

TLDR: THe RN Stack With less Suck I’m Using

Heres my list of essentials, based on our recent tests, research and experience working with React Native, your choices may differ, but I hope they’ll be considered in the native context.

  • Routing with Wix React Native Navigation v2
  • Native Components over a single UI library
  • React Native Firebase & Google Cloud for our backend
  • Redux & Redux Sagas for complex state
  • redux-persist with RealmdB for persistence

The setup of these dependencies, in concert, will be more complex than a simple npm install… or yarn add ... and probably feel frustrating for the first day or two as you get your head around them. Remember this is a different animal to building a web app. Be in it for the long game. Future you will be grateful.

Remember to Put the NATIVE in React Native

Consider every component, screen, library and architectural decision in your React Native App carefully. One poor choice can have real implications for your end users, as well as your developer experience. Remember to put the NATIVE in your React Native apps.

Paul van Zyl is a full stack JS and Golang developer, award-winning product designer and founder at Sigma Digital, a decentralized product design and development team. follow him on Twitter.


Published by HackerNoon on 2019/02/23