Downsides of React Native

Valtteri Laine
6 min readAug 2, 2021

The benefits of React-Native (RN) are clear. You get two birds with one stone, iOS and Android. On top of that you get to use React, which is commonly used with web development also. What could be better?

If it only were so simple!

If you are already using React-Native. Don’t worry, it’s fine.

React-Native May Require You To Code in Four Different Languages

With RN applications there is always a risk of having to dive into native coding. Meaning when you got a job as a RN developer, you actually made a contract to code Swift, Java, Objective-C and Javascript. Handling this many programming languages is challenging for anyone. Your RN app might be 95% Javascript, but often there is something that needs to be done on the native side.

RN has a good selection of ready npm packages. However often you want to use some iOS or Android library. With RN this means you either have to find a RN wrapper or implement one yourself. Making and maintaining these wrappers is time consuming. Also debugging can be annoying as you have be ready to debug native code as well as Javascript.

Often you end up using somebody else’s wrapper, but there is no guarantee that it’s maintained, or it works as intended. If there is a problem, you anyway have to make a deep dive into the wrapper implementation.

Wohoo! Finally I understand npm, Pods, Carthage, Redux, Java, Swift, Objective-C! I’m ready for React Native! Wait… What the heck is Gradle?!?!

Longer Build Times With React-Native

Yes, in RN you can see javascript changes immediately. However as mentioned before, you often have to code with Swift or Java as well. Seeing the native code changes on screen with React-Native is considerably slower compared to native projects.

Let’s picture a scenario. After a year of coding RN with Javascript, you are finally faced with that one feature or bug, that requires you to work with Android and iOS without React Native. Yikes!

First, you have to code with language you may not know much about. Second, every time you make changes, it takes AT LEAST 30 seconds to run that code, and see if it works. This is a huge time sink, and some developers might even get completely stuck. In worst case scenario the feature needs to implemented for Android and iOS which means coding Java, Swift and Objective-C. Not so fun for your Javascript developer!

If instead the app was developed without RN, the changes would show up in 1–2 seconds. Around 15 times faster compared to RN. Also the developers would be working with programming languages they have actively been using.

Another scenario where build times matter is build pipelines and testing. Often developers want to run E2E tests against each branch before approving and merging them. However RNs slow build times can make this unfeasible.

Also when distributing a new versions of the app, it’s nice to have builds as fast as possible. For example, when you finish your work day and you want to push a new version for store review, you don’t have to wait for an extra hour to get the bundle.

Here is a rough comparison of build times. All builds are with default template projects in dev mode, and with zero code changes between builds. RN includes installing node_modules on 1st build.

  • React Native iOS, 1st: ~ 4 min 20 s
  • React Native iOS, 2nd: ~ 30 s
  • Native iOS 1st: < 30 s
  • Native iOS 2nd: < 1 s
  • React Native Android, 1st: ~ 2 min
  • React Native Android, 2nd: ~ 25 s
  • Native Android, 1st: ~ 40 s
  • Native Android, 2nd: < 1 s

As you can see native projects are several times faster to build than RN.

On the positive, React Native adds meme breaks into your day!

Different design guidelines for Android and iOS

iOS and Android have different design guidelines. Google has developed Material design while iOS has Cupertino design. If you follow Material Design guidelines your application could look out of place on iOS, and vice versa. It can help to think of iOS and Android apps as separate projects to overcome this design challenge.

Some big companies go around this by developing their own unique looking design guidelines, but this option is costly and not available for everyone. Some of the differences are in how back navigation works, typography and so on. You can read more about the design differences from here.

Latest Functionality Not Always Available

RN abstracts iOS and Android. This means that whenever iOS/Android releases a new feature RN has to wrap it in Javascript, document it and release a new version. This is IF they think that functionality is worth implementing. So if you want to enjoy the latest and greatest features in mobile development, you will have to wait for the RN team to maybe implement it, while the native apps are already ready to go.

React Native Has More Bugs Than Native

All platforms and frameworks have their bugs. React-Native abstracts iOS and Android development frameworks. As a result React-Native has the problems of both iOS and Android platforms as well as RNs 1.5 thousand unresolved issues.

These issues vary, from users not reading the documentation to serious problems, like unusably slow performance. Either way it’s 1.5 thousand issues you don’t have to deal with if you simply develop directly with iOS and Android.

Yikes!

Poor accessibility support

In summer of 2021 EU started to enforce accessibility standards for some mobile applications under threat of fine. To my understanding RN can pass these standards, but for an optimal experience you have to add some functionality. However RN team is working right now on an accessibility release, but it’s still not as comprehensive as just making a native project.

Also RNs accessibility API doesn’t always work the way you’d expect. For example, prop accessible={false}, hides the element from screenreader on iOS, but not on Android. Instead on Android you also have to set importantForAccessibility=”no”. There might be a good explanation for this, but it sure isn’t obvious. Basically because same props do different things on each platform, you have to rigorously test both Android and iOS on a real device with a screenreader, and often add some platform specific code. The worst part is when you get Android to work, you might have broken something on iOS and vice versa.

Here are some things that are completely missing with React-Native accessibility API, but exist on iOS and Android natively.

  • Adjusting screenreader read order
  • Missing screenreader translations for components (read here how to fix)
  • Queuing screenreader announcements (iOS simply interrupts existing)
Impaired vision is just one reason to use screenreader.

Near Native Performance

RN performance is near native, and RN is faster than any WebView based technology. However if you want that remaining 5–10% performance boost and less battery drain, then go native.

In my opinion RN team has done well performance vice, and performance isn’t an issue. If some feature would be considerably faster implemented on native side, you can do that, and still use RN for everything else.

If you want to make a deep dive into the performance side of React-Native I recommend reading the following: BrainHub, Perficient, The React Native Log. They include benchmarks that show that RN delivers near native performance.

RN vs native performance is like first place versus second place. Second place is fast. Just not as fast as the first guy.

Summary

I’m not saying to never use RN. It often is the right choice, and it can cut down development costs significantly.

However with some use cases the extra bugs, smaller API, slow build times and not quite as good performance can cost you more than React Native ends up saving in the long run.

When choosing between native and RN, one needs to have good idea of upcoming features, accessibility requirements, will there be in-app payments and so on. It simply shouldn’t be an automatic choice.

If you liked it or if you think I’m wrong let me know! Happy to hear whatever thoughts or feelings this article invoked in you. As a side note I’ve happily developed with RN for over two years, and will continue to do so :)

--

--