React Native Limitations that Facebook doesn’t want you to know
By now, most React Native developers have probably heard the news that Airbnb, Udacity and few others have moved away from React Native. Although, it’s kind of weird to witness a move suddenly but it’s inevitable for an organization to ‘sunset’ a technology or framework which is not going to be fruitful in the future.
Every framework has some limitations, so does React Native. Understanding these limitations is extremely important before you start developing your mobile apps. In this article, we are listing some of the most common limitations in React Native. We hope to help you avoid some really big pains in your react native development. If you want to know which cross-platform framework will be best for your use-case, we have written some detailed cross-platform framework comparisons such as React Native vs Ionic or React Native vs Swift. It can even help you decide whether react native as an application platform is right for you or not.
This article is divided into two parts:
- First part talks about some of the limitations that are commonly known
- Second part consists of some list of limitations contributed by expert developers and technology leaders of organisations such as Facebook, Wix, Airbnb etc.
PART 1 – Commonly known React Native Limitations
For the time being, there are still some limitations where in current React Native version is concerned which we have listed below:
Note: We are not in any capacity implying that React Native is bad. In fact, React Native has been one of the biggest cross-platform framework with a splendid ecosystem of tools, libraries best databases.
A Study On React Native Performance Issues, And Insights On Improving It
Cross-platform, but often requires native developers
Also, we figured out that while using SDKs like Google Analytics for mobile – you need to understand the inner working of the native library to make sure you understand how to integrate it with you react native app without breaking anything.
Some support is available from tools such as Expo, making react native more convenient and helpful.
Same components might behave differently in react native
Under cross-platform development scenarios, it is often assumed that an app component written on a cross-platform or hybrid framework would behave the same on both iOS and Android.
While that stands true for the majority of the cases, it doesn’t exactly work like that in a few use cases.
Require developer expertise on Three different platforms
Abstraction Layer Limitations
In order to generate more functionality on React native, an abstraction layer is created on top of the native platform. Any bug encountered in the abstraction layer can bring in unexpected bugs within your application. Not only these bugs are extremely difficult to diagnose, they are difficult to pinpoint as well. Having abstraction layer in place also implies that you would be dependent upon third-party services or libraries to keep your framework up-to-date and prevent it from breaking.
Forced to implement custom designs in native language
Another side of having these abstraction layers is that you will have to implement custom designs in platform native languages such as Java, Objective-C or Swift. This often reduces the benefit of keeping a hybrid platform and frustrates mobile app developers.
Dependency on Third party libraries
React native is awesome, no doubt there. But, for your specific use cases, you need to assess and check whether the implementations are robust enough.
Take the case of Tab Bar as an example. You would find proper support in place to have a Tab bar in iOS, but Android lacks support.
When things like these happen, you often have to pick up third-party resources or libraries. For another year or so, this seems like to be a case for another year. So, no matter what app you are trying to build always look whether third-party solutions are available or not.
Outdated third-party libraries
We talked about heavy dependency on third-party libraries in the section before. What you should also know is that React Native update often happens more frequently. And when that happens, third-party libraries and services often get outdated.
Depending on the community support for a particular library, you can expect it to remain updated or face app breaking issues.
No support for parallel threading or multiprocessing
For instance, if you require your app to perform live chat and video surfing in parallel then you can’t expect that with React Native.
Debugging styles are bit inconvenient thing in React Native
Debugging styles in React Native might be bit inconvenient for an immature web developer as you can’t depend on chrome debugger to edit each element’s property differently.
Though React Native offers you a built-in-inspector, it is quite a basic thing at your disposal.
You would find it a bit annoying to debug styles in case when it grows and covers lot of screen. Simply put, debugging styles in React Native can quite mess up the things for you.
iOS Deployment is not hassle-free in React Native
In React Native, you will find it annoying if you decide to test your app by using testing services other than Apple’s own testing tool Testflight. Because you may have to deal with problems of obtaining the necessary certificates and provisioning profiles at the same time.
However, on Android the entire process is much painless and smooth except when you want to update your alpha version which can take up to 24 hours straight.
React Native vs Swift – A Side-by-Side Comparison for iOS Application Development
PART II – React Native Limitations experienced by renowned community experts
As mentioned above, this is the second part of React Native Limitations which is contributed by some top-notch experts of React Native community.
Leland Richardson, Software developer at AirBnB
Overall, I think I would categorize problems/limitations into three camps:
“Fundamental” problems would be those that are limitations of the react native architecture directly, and are unlikely to change. We can only work around them and minimise their impact.
Following are some fundamental limitations of React Native:
- Bridge Serialization
All data has to get serialized into JSON on its way in and deserialized on its way out. This double ser-de pass can be costly for data-intensive problems. It also prevents sharing any memory between native and JS.
- Single threaded ness
JS is single threaded, which means there will always be limitations around doing meaningful work in the JS context. This can be worked around with really good scheduling paradigms (e.g, react fiber), but is always a limitation.
- Initialization Times
Any code written in JS needs to be parsed and executed in the JS VM. This has a cost and compiled code and binary loading will always win here. There are potentially some ways to improve this with bytecode caching or something, but that still seems far off.
Implementation problems are those which I think can be fixed but have not been yet. Sometimes these problems are side effects of the “fundamental” problems, but I think could still have compelling solutions.
Following are some Implementation problems in React Native according to me:
- Robust view recycling
Both iOS and Android have really robust recycling abstractions with RecyclerView and UICollectionView. There is some difficulty recreating this on top of react’s architecture as well as react native architecture. There are some attempts to build more optimized list views in RN, but they all have trade offs and I’m not that impressed with how far the community has gotten here so far. That said, I think the current ceiling here is higher than people think and we have worked around list-related problems successfully.
- Gesture Systems
The RN gesture system is currently mixed. There’s some stuff that lives in JS (Touchable and PanResponder) and other things that live in Native with the platform gesture system (ScrollView). This means that when you have the two of them competing with one another, you run into problems. Ultimately I think we need to move to an entirely native gesture system with some JS declarative APIs similar to what we did with the Animated API. react-native-gesture-handler is on its way to bring this, but more work needs to be done.
Finally there are “Socialization” problems which can be solved by the contribution of community.
- Dynamic typing
This can be solved in large part with typescript, flow, or reason. This is not the common path though. This concerns a lot of people in the native community a lot.
- Overly web focused
RN community is all about the web and is all web engineers. Native engineers feel this as threatening and the two communities need to find some common ground I think.
- Average quality showcased is dramatically lower than for native
This just seems to be true. We need more high-quality examples of React Native succeeding.
- Tumultuous history of failed “write once, run anywhere” attempts
People have a bad taste in their mouths from previous “failed” attempts at this like Cordova/Xamarin etc.
Those are the main ones that I can think of. To be clear, a lot of these I think are platform problems but a lot are things that tend to not matter > 95% of the time. And when they do end up mattering, it often just makes experiences a little bit worse, but not to the point where it’s a deal breaker but that really depends on the application of course.
Gant Laborde, CTS of Infinite Red
“ Each new part of the machine increases the complexity, deprecates some unpopular use-case, and possibly fragments community. When you take a step back and look at the toolchain, you get long list dependencies that are individually evolving. The biggest limitation to React Native app development? To continue evolving without alienating one another. Communities, conferences, and transparency are the key. If we ever drop the ball on that, then whatever the current ailment of RN is, will be its greatest limitation.”
Spencer Carli, Web and Mobile app developer
Eric Vicenti, Software developer at Facebook
“The biggest limitation of React Native, in my opinion, is the inability to easily create performant gestures and animations. I recently gave a talk about this where I go into details, and I discuss the approaches the community is taking to fix this limitation”
Houssein Djirdeh, Software developer at Rangle.io
“Here are some React Native limitations off the top of my head:
- Navigation is not easy. There are many many libraries out there for navigation but it’s still something that isn’t the easiest to build in terms of having a completely fluid and maintainable navigation flow for both iOS/Android.
- Performance intensive operations. This is where the JS bridge of React Native can some problems if intensive processes are running that would probably make more sense doing directly on the native thread. This is something many developers probably won’t have problems with, however. “
Hector Garcia, FrontEnd developer at Xing Barcaelona
Afterwards, we switched to https://github.com/invertase/react-native-firebase which uses the native Firebase libraries for both iOS and Android, so we don’t need to do that anymore and it’s been flawless and way more performant so far.
All in all, my experience has been awesome though! We achieved things that previously would have been unimaginable, such as being able to reuse around 90% of our code between iOS and Android.”
Leo Le Bras, Creative developer at Getwino
- The first one is the navigation. Solutions such as react-native are not effective for production. Performance is the main problem today. Fortunately, there is react-native-navigation that offers very good performance but it’s not yet customizable enough (for v2).
- The management of multi-threads is nowadays difficult to achieve.
- It is difficult to maintain good performance on older devices (e.g. iPhone 4).
- React Native is not yet well supported by Flow and Reason.
- Memory leakage for Android
- The community is mostly composed of people from the web. There are not enough people from Swift or Java.
Martin Konicek, Software developer at Monzo (Formerly React Native developer at Facebook)
Here’s a top list of missing features: Missing features of React Native
I also thought this talk by Brent Vatne explains some other areas pretty well:
Gabe Greenberg, Founder G2I.co – a talent platform for engineers by engineers focused on React, React Native, GraphQL, & Android/iOS
- Any time you abstract away from complexity you sacrifice speed.. so that is the main issue with RN… speed on Android devices (older ones) and older iPhones.
- 3D games would be un-appropriate for RN
Zachary Gibson, UI developer
“I was recently working on re-creating this (File attached below) but border radius animation can’t be natively driven so I couldn’t come to full parity on the drag down interaction. It was a real headache.”
Roman Liutikov, Software engineer
“The biggest limitation was poorly written native modules and perf sensitive modules written in JS, instead of native.”
Daniel Harvey, Software Developer
“In my relatively limited experience, the main limitation is in graphics manipulation – the best practice drawing surface that I have found still seems to be a Webview with a canvas inside which is doable but rubs against the react workflow somewhat. That said, perhaps I am just choosing an inappropriate use case – there is a reason intense graphics stuff is usually coded pretty bare metal rather than through layers of obfuscation – and for less graphically intense applications.”
Gaya Kessler, Freelance Web Developer at Clevernode
“There is one thing which is on my mind, though it’s not some sort of limitation. It would be great if stateless functional components would support Hot Reloading. Not having to wrap every component in a class would be nice and clean.”
Adrien Thiery, CTO at OSEDEA
“A few limitations of React Native that I’ve had experienced so far are:
- Doing background stuff: having background tasks that run even if your app is closed is not an easy task (if doable at all, I kinda remember there might still be an issue on the react-native repo about that)
- Navigation/optimization: if you don’t use native routing or optimize your “JS routing” like react-navigation, things can go pretty heavy pretty fast. Throw in a bunch of TabNavigators inside a StackNavigator
- Managing props and render on the native side: I am not a native developer but I think there might be something not right in the way we get props down to the native side. All the setters are not called at the same time so we need to call the “render” function of the native component with a filter on the props that have been set to avoid rendering something with not enough information or something. That might be a problem in our implementation though
Aaron Greenwald, Software developer at Wix Engineering
“If I had to pick one limitation, I’d pick my current struggle, which is animations. I’m in the process of trying to get some fancy dynamic animations done and running into issues getting the native components to communicate properly with React Native. In general, performance can be a struggle. The bridge can get very busy and performance will degrade. And because communication between native and JS threads is async, handling user interactions in JS isn’t consistently fast.”
Jarret Moses, Software Engineer at Big Human
“According to me, the biggest limitation is when animations get very complex and calculation heavy (especially on certain layout changes where performance is key and useAnimatedDriver is not available). While maybe at times possible, the overhead of time spent to perfect them can be unreasonable. Luckily there are helpful packages out there such as Lottie (By Airbnb) to ease these use cases. “
Although React Native has completed more than two years since its launch, it still has a long way to go. The limitations of React Native mentioned above are the ones which are commonly experienced by React Native community. Still if you are facing any limitations which are not in your favour, you are free to choose any different cross-platform development framework. But we strongly believe that, the choice of a framework should be based on your project use case.