Developing a ReactNative (RN) app for Android and iOS for the last 2 years I have more and more doubts that ReactNative is still a good choice for mobile apps these days.
Another alternative would be to write native Java for Android and objective-C / Swift for iOS and that can also be a good or bad choice depending on what you plan to do with your app. The more sophisticated your app will be regarding UI/UX and performance the more likely this can be a good choice to have more or less two apps with different development teams and maybe some shared roles, but in the end two products with the same name, but for different targets.
On the other side, the more you're focused on functionality over UI/UX and other non-functional criteria, the more likely is that a hybrid or cross-platform app is a good idea, because you only have to maintain one application. So to put that benefit into numbers, it's possible that more than 50% of development resources can be saved and that's a lot.
Before we continue I'd like to clarify the difference between hybrid and cross-platform technologies. Articles often mix them up or use them as synonyms but actually hybrid apps have some embedded browser backend like Ionic/capacitor where you can also write native plugins and utilize native APIs, which is impossible in progressive web apps (PWAs) that run in a browser sandbox.
Cross-platform apps on the other hand side use a native backend controlled by a unified runtime. E.g. ReactNative looks like the usual JSX output we have with React in the browser, but it's forwarded to an engine that mounts native UI components.
A bit of history
Mobile development really had hard times when there was more than Android and iOS and the browser wasn't well integrated. That changed over time. Actually you "only" have to support Android and iOS today and the browsers have so much power with new APIs like PWAs that you should of course even consider to use the plain browser as a suitable frontend.
Because of the reason that you have limitations in your browser sandbox it can also be difficult to make a good decision for now and the future, but good news is that around 2015 when browsers started PWA support and becoming more and more an app look and feel, there already was PhoneGap (known as Cordova framework nowadays) and Ionic/capacitor and Facebook announced ReactNative as a new cross platform mobile technology.
Today we still have PWAs in a browser sandbox with known limitations we cannot circumvent, PhoneGap/Cordova end of life was in 2020 so not a choice anymore, and we have ReactNative and Ionic/capacitor.
There is more like e.g. Flutter or Xamarin backed by Google and Microsoft, but it seems like their communities don't really grow fast enough to compete with the huge JavaScript/TypeScript community which is literally running the web front- and backend as well as being used in ReactNative or any hybrid app technologies like Ionic/capacitor. So I allow myself to question if Flutter or Xamarin should be recommended as mobile development technology today, which may of course change in the future, but for me today it's hard to believe.
That's the reason why I only see real native development for Android/iOS and JS/TS based hybrid- or cross-platform app technologies in the near and far future. With my ReactNative experiences the last 2 years and proof of concepts with Ionic I did for the current app I finally have an opinion for the technology I would use for my next mobile app. Let's start with some of the problems we faced using ReactNative.
Problems with ReactNative
Disclaimer: Some of the problems might not occur anymore or are due to reasons we caused. In the end it took a lot of time for investigation and I can't remember I had to deal with such partly nasty problems in other front-ends.
iOS HTTP2 nginx compatibility issue
The cool thing about HTTP2 is that actually the networking layer of any technology can upgrade to it at runtime if the server supports it without having to change app code so it's transparent for the app.
With a specific iOS version 14.x and higher we got strange HTTP2-protocol errors. Debugging down into ReactNative networking and reading native error logs we finally found out, that it seems like there is a problem when we send requests in parallel. Searching for it on the internet takes us to different threads where someone said it should be fixed on iOS while others say it should be fixed for nginx or forcing HTTP1. Only latter would be possible as a quick fix, but somehow experimental and as nginx is quite system critical component we decided to make iOS requests in serial for the affected versions and hopefully can remove that workaround after an official nginx version that fixes it or the iOS versions we support have it fixed.
I can't tell if that was a ReactNative issue or not, but I can't remember having such problems in the browser and the nginx version is an official AWS EKS ingress nginx.
RN updates
One of the golden rules of mobile development is that you should not wait too long for making updates. It's a ticking time bomb because in my opinion iOS and Android API development is still on a journey where they do not focus on API stabilization a lot, but make frequent breaking changes to new APIs while deprecating old API versions. That kick-off has an impact to all dependencies which also impacts your application.
That means ReactNative updates happen frequently and many dependencies especially new ones may not support yesterday's RN versions. At some point we had everything we need to implement new features without having to add new dependencies and then you should better have a different concept of keeping an eye on updates.
In our case we ran into the next nasty conceptual problem that forced us to add a new dependency which was not compatible to our current RN-version. Because there were no needs for our customer to update RN for about 20 months our update recommendations were not prioritized high enough and it was postponed to the future. But then we had to update RN and here comes the next negative criticism about RN.
We actually knew that it will not be just a small task for the afternoon, but the ReactNative update helper will run into patch problems and some manual effort is needed. Not talking about source code, asset- or dependency metadata like lock files or auto generated json assets we have:
- iOS: 1600 lines of config
- Android: 500 lines of config
And we also don't use manual linking which would blow up configuration so this is actually the raw configuration setup checked in to the code repository. Whenever there is new RN version, they provide a new empty project template and the update helper tries to patch your project. The larger the diff is through version updates, the likely it is that the patch fails. And that's what happened when we tried to jump from 0.63.3 to 0.66.3.
The diff was meaningless and so we compared the files by hand. Until that day we haven't had that much experience with iOS and Android setups. It took a lot of time, especially the iOS setup, because you have to modify and run the installation until it somehow worked. At some point one or another dependency could not build and you had to investigate why, until you have the next problem in the setup where the error message doesn't tell you anything about the actual problem, but like "cannot read /some/xconfig.rb" which looks odd as it's an absolute path, but having a look at the custom script reveals that some environment variable is not set for "${SOME_PATH}/some/xconfig.rb" and that's just one example out of many.
The good thing is, that it's more or less iterative, but we needed many, many iterations and I think almost two or three weeks to get everything fixed. Of course we also had to update npm packages because finally when we could deploy the application to our devices, it didn't start there because of an error at runtime.
In short, the iOS setup is mess of xcode project configuration no human should actually read and with custom inline bash scripts running Ruby or node.js scripts setting hidden environment variables and all in all really hard to debug. Android setup was much more easier, but also took some time.
RN "core" packages issues
The ReactNative runtime provides some of the APIs you also find in the browser and a react setup, that transforms JSX into native views, but it's lacking some of the core functionality you need in mobile apps starting with native screens and e.g. navigation gestures and ending at filesystem access. RN community is somehow fine to move that responsibility to npm packages that brings such fundamental features to the mobile app. Referring to the last section about RN updates those "core" packages are very tightly coupled to the runtime and the operating system's API that we of course also had to update them. And then one package broke our debugging setup.
It's important to be able to debug the application, but we don't need it every day. After the update journey we were so happy to consider it finally as resolved, but we were so wrong as debugging now freezes the application and it's not possible anymore. The solution was to change the underlying JavaScriptCore (JSC) engine to Hermes and use Flipper as tool.
Although it's feels like the change of the JS engine is the next upcoming nightmare it was really just a one line configuration change. Introducing Flipper was more to do, but in contrast to the RN update it was okay.
Debugging
Since ReactNative is not a hybrid app, although it feels like we have JSX and CSS, we can't use well-known debugging tools like the dev tools in the browser. It's not quite correct, because indeed the React-Native-Debugger is an Electron application simulating the runtime on the local machine and has dev-tools where you can debug network requests like in the browser, but not everything works as expected (like file uploads).
Same for debugging the UI where you can update CSS classes or styles in the browser dev-tools, but with ReactNative you only have some smaller debugging features. Either use them or default hot module reload and hack in your IDE and check your device which also sometimes doesn't work for styles. If you know what browsers can do for debugging you feel a bit far away or even lost in ReactNative, although it seems to be getting better over time like Flipper is much more better integrated for debugging.
What else if not ReactNative?
As I've mentioned before this is very opinionated, but the remaining technologies for mobile app for me is still native development or Ionic / capacitor. The decision to use one or another shouldn't be too difficult, as you can have the same technology for iOS, Android and browser apps with Ionic / capacitor, while you may want to stick back to the roots of native mobile development for maybe serious UI performance reasons or you already have native development teams with good performance.
Ionic / capacitor
Now I owe you an explanation why I always wrote "Ionic / capacitor". So capacitor is the technology that brings the browser runtime to the device, while Ionic is a set of UI components that should look like being native. So it's also possible to drop capacitor into your web app and make it a mobile app, if it has a responsive UI.
Comparing it with some disadvantages of ReactNative
- Debugging on the local machine in any browser with all browser tools is always possible and you can also use Safari for debugging your iOS application or Chrome for Android. Anyway from our ReactNative experience most of the debug sessions were not device related and within a browser runtime it's more likely not a device issue
- "core" packages are maintained by the Ionic community and backed by the company itself
- full-featured browser runtime on mobile devices using native web-view and the browser itself for desktops allows the use of the browser APIs, like fetch-API, web-worker or IndexedDB should be possible everywhere, while WebSQL is only supported on chrome based front-ends, like Chrome or Brave for desktops or the chrome-based web-view on Android, but not Firefox, Safari or iOS at all using some Safari-based web-view.
- like with ReactNative, we don't have to make a full build every time because hot module reload can update the JS source, but on the other hand a full capacitor build takes a few seconds, while our current ReactNative application needs about 2-3min for a full build and sometimes like when you have to update everything a faster build is better
That comparison is maybe a bit unfair, because it's a full-blown RN app vs. an almost empty Ionic app and of course build times are better and whatnot, but I assume it will not have the problems we had with ReactNative:
- The application is using fundamental browser APIs in the first place. That is primarily a browser DOM out of HTML, CSS and JS for the UI, which obviously never breaks. Then the fetch-API or IndexedDB which is provided by the web-view, but not implemented by capacitor also have very stable APIs.
- Gestures, animations and navigation is maybe not 100% accurate to their native UX, but Ionic is again using browser APIs and we can use well-known libraries like react-router for navigation. It's much more easier to think in URLs than in screen names and parameters.
- Finally, it's also not possible to break debugging :).
Conclusion
It's very important that as a developer we are not too far away from the code we write. That means we should be able to frequently change and verify it with almost no costs and mature technologies like the browser have so many introspection features for apps, that we may only use a few, but we're at least standing on the shoulders of giants.
I also don't see a problem, that a web application looks and feels like a mobile application and I think that "one UI for everything" is mostly a good idea and saves money. If you want to change some UI components for the desktop then simply go left or right, but not for the whole application because it's mostly not worth the time, I think.
Ionic is a very good example how to achieve that and from what I read and tested within the proof of concept, I've already recommended to switch to Ionic away from ReactNative.
Top comments (36)
This was a really insightful post on your experience with React Native! Thank you for sharing that! Did you happen to look at Flutter at all? I’ve been using for a few years now and have been loving it.
Hey Brad,
thank you for the feedback.
I just did a "hello world" with Flutter, but nothing that really allows me to criticize the technology itself. My problem is just about the community trend, that around 2012 Dart and TypeScript came out and the web community went in the direction of TypeScript. As far as I know Flutter is only possible with Dart.
Depends on what you're talking about - if you talk about web tech as such then it's absolutely Typescript that's big, but if you talk about mobile dev then Flutter is a serious player ... but it's definitely not "web", that's why it's not a "thing" in the web community. Yes and Flutter is based on Dart, not on Javascript or Typescript ... I don't see that as a problem, I mean there are people programming in Python, in PHP, in Go, in C# ... Javascript is not the only game in town.
You're right that for a good reason not everything is JS, but when you don't need all of those fancy app features, I would always vote for hybrid apps where I can let my web team work on a mobile (web-like) app and even more if we also have a website.
Would you say Dart is or could be a thing for the web? I've never heard of it outside of Flutter in the past. If I remember correctly, 10yrs ago there shall be types in JS so among others Dart and TS started their missions. According to a survey the Dart community really loves it, but not so many are working with it.
I also don't see a problem when Dart comes in, but I think it's not about "can you write or learn Dart?", but "do you have enough experience to kick off a Flutter app?" so you also don't have to rewrite it after one year.
Jumping back to Ionic: your pool of developers making projects with Angular, React, Vue and so on is very huge.
The question is what you have and what you want :).
Dart itself is niche, I don't know if anyone really uses that, lol ... Flutter is really THE killer app for Dart, don't shoot me but outside of Flutter I don't think anyone takes Dart seriously ;)
And oh yes, I think in many (most?) cases a hybrid app/PWA just hits the sweet spot, native is required only or a minority of use cases I would say ...
Great :). At least you've got me to check out Flutter again and maybe read my article about "good bye Ionic, hello Flutter" then :D.
But why the hell seems Dart to be the best language for Flutter? That really makes me nervous :D.
Why does it make you nervous? It was just designed or "invented" that way (by Google, if I'm not mistaken) ... they wanted a type-safe, compiled language, which Javascript isn't (Typescript is still a "kludge" lol even though a beautiful one).
Yup, I've tried most solutions and flutter is by far the best developer/user experience, it's a joy to work with!!
I've heard nothing but good things about it as well ... people who are still writing code two times (once for Android with Java/Kotlin, and once for iOS with Swift/Objective C) should really rethink what they're doing :)
Yup, it's one of the best frameworks I've ever tried, since using flutter I think I've gained at least 10+ years of life xD Jokes aside, I really think it's worth trying out, you won't be disapointed... You will have a lot of "oh so this is how it's supposed to be done" moments. No more weird APIs, hacks, layers, bullshit, just start coding and build for any platform you want... what else could we want??
Spot on, based on what I've heard about it :)
Great post Philipp! On the topic of device debugging, this is absolutely possible. We have docs on that here: ionicframework.com/docs/troublesho.... Another popular tool for iOS debugging is inspect.dev.
I'm glad you mentioned the community size aspect. One thing people don't always realize is that Ionic + Capacitor is part of the broader web ecosystem, while Flutter/Xamarin/etc. are self-contained/closed ecosystems. Ionic devs can use practically any web library, share code with their web app, and use their existing web and web framework experience. If you're a React dev then using React with Capacitor will be the most like building with React on the web where all the React libraries you want to use pretty much just work (which is not the case for React Native).
This has given the platform strong staying power since developers see it as an "electron for mobile" where they are basically building a web app but extending it with native mobile functionality.
Hi Max,
I've edited the part about debugging.
Thank you for that and of course for having Ionic at all :) !
I appreciate you've read it.
cheers
Philipp
Thank you for the article. I have the same feelings as yours. But I also didn't rewrite RN app to Ionic.
I had a lot of problems with RN. Maybe I'll have them with Ionic too :)
matchAll
didn't work, so I had to rewrite a module with a polyfill.scrolling speed in View (programmatically) is not custom, but fixed. What is 1 line of code in Ionic I don't know how to do it in RN after hours of research (I think it is impossible).
position: sticky
-- two words in CSS, I don't know how to achieve it in RN.I was pissed off, when in Expo Video, there wasn't an attribute
playsInline
and on iOS my app looked so ugly... And there wasn't a solution. After months they fixed this issue.Expo weights (60-70mb) -- it is even "Hello world" app.
Playing video and audio is buggy there, as well as a web version too (it was experimental).
Finally I refused it when at some point the app was building for hours without the result. I am so tired of RN/Expo surprises, I burned out and fell into severe depression for months after 6 months of development.
I hope that in Ionic web will work as expected, without surprises.
But I don't wan't to step out of web, because I am neither smart enough to learn swift, kotlin, c# or dart (in addition to JS) nor rich to hire such experts.
I completely understand why working with a "hybrid mobile" tool like Ionic is MUCH easier than working with a "native" tool like RN ... the question is just - do you absolutely require a "real" native app, or is a hybrid app (based on WebView) more than "good enough"?
In the latter case, by all means I'd go with Ionic (or comparable 'hybrid' tool) because it's just much quicker and easier to work with ... if you MUST have a real 'native' app, then well, it's either native iOS/Android, or RN, or Flutter - I've heard many great things about Flutter and maybe you're discounting it a bit too quickly.
But the decision between "do I really need native" and "is hybrid (more than) adequate for my needs", that just depends on your requirements ...
I'd guess that 70 or 80 percent of mobile apps are just fine as 'hybrid' or PWA apps - typically apps that are content focused and that aren't doing technically crazy complex things ... in all likelihood performance in those case is great if you use hybrid/PWA, and you don't gain much by building them as a 'native' app.
There's another option, too, that we see growing in popularity: build a native app shell using whatever tech your team wants to use, and then mix in web experiences in a micro-frontend fashion. Our Portals project does this and it's pretty interesting seeing die-hard native app teams embracing this approach to move faster and enable other teams to contribute to an app: ionic.io/portals
Interesting !
Hi, Phillips
Nice article. It seems my story and ours are going in the opposite direction.
Ionic is great! I worked with it using the Angular part for like 3 years, but have not really tried the Vue part extensively.
Ionic-angular is cool. We enjoyed every part of it. It just works well. We integrated plugins; they work well too.
As for ionic-react, we had a lot of issues, beginning with the navigation. Ionic-React-Router occasionally lags. Some people even suggested using pure react-router instead of Ionic-React-Router. Then we also had issues with plugins; some work and some do not.
However, in React Native, which I recently came across and also from what I have heard from developers in my country, React Native is a goal here.
I posted a lot of questions on stackoverflow and ionicforum concerning ionic-react. I got no positive answer. It seems people don't really know much about it.
Most of your issues are related to iOS. I think 2 years of experience in React Native is a lot for you to decide, but I see people with 4 years of experience in React Native with minimal complaints.
Lastly, what I love about react-native is the react-navigation lib. Almost everything is done out of the box. Ionic has an animation builder API for you to create a custom animation, but I think react-native plugins do something beautiful too.
They all have their pros and cons. For me, I think react-native is cool.
Ionic-angular is cool.
Ionic-react is not yet cool.
Welcome to the ionic world 🌎🌎
I have used both for client projects, more ionic than react… but there are definitely times when I wish there was a larger Ionic community building and maintaining plugins. Often where I get jammed up is around native plugins. A perfect example is for native maps, if you look at the map native plug-in for maps in ionic vs react native, it is like night and day.
I just use JavaScript web based solutions and for maps now, but I think the plug-in ecosystem is a place for growth in ionic community
Goodbye RN, I am investing my time learning .Net Maui
What do you say about it? Target is iOS, Android?
I came to the same conclusion a while ago. Most apps are content driven, which can easily be done in ionic / capacitor and with decent performance.
I never thought I'd see someone prefer Ionic over anything else really, what a mad man!!! For me ionic is the worst framework for cross platform apps I've ever used, it's painful. Though choice is good and If you enjoy and get value out of it go ahead!!
Hey Keff,
what exactly is wrong with Ionic?
To be fair, Ionic is just a couple of web-components not even very opinionated because they try to simulate iOS and Android behavior. You can use the big three Angular, React, Vue or just web-components. If you don't like Ionic UI/UX then put whatever you like in to the capacitor box. And finally if you don't like web-apps at all what do you use?
I should've said Ionic/Capacitor actually, the whole setup. Worth noting that I haven't tried ionic in a few years, maybe the problems I had have been resolved.
I worked with ionic for mobile app development for a couple of years (iconic with angular), and from my experience, it's a mess, prone to bugs, excessive templating (with angular at least), strange conflicts with plugins, and overall a pain to work with when the project gets bigger. I guess it's up to the developers to prevent this, but having tried other solution I can tell with confidence that quite a few of this problems can be solved by designing the framework correctly.
For me the biggest drawback is the amount of layers that Ionic has, making it really easy for one of them to give you problems.
My hate might be subjective though, I did not have the best experience working with it and it might've not been the frameworks fault... nevertheless I don't think I fancy trying it again, not react native either for that matter. I really don't like using JS/TS frameworks for these scenarios, they allow too much.
I get what you're saying, I used an old version of Ionic, 6 or 7 years ago and it was okay but not ideal ... however I think you should ultimately base your judgement on an up to date version - and don't forget that you can now use React or Vue with Ionic (I used Angular 1 which was okay-ish, wouldn't touch Angular anymore).
Yup I agree, I'm aware of this as I mentioned in the comment, it might've been a mix of working on a badly maintained project, old ionic versions + angular 2+ plus other factors.
When I worked with Ionic, React was beeing added, then Vue was also added. But I did not have the chance to try them out, either way I also don't enjoy React at all, vue is alright though.
I probably should try it out again, though I don't fancy it at all xD
Yeah I also like Vue more than React :)
I might be dabbling a bit with Ionic for an MVP in an upcoming project, although I told them "do yourself a favour and use Flutter instead", lol ... but we'll see.
You know when I became hugely and thoroughly convinced by the web/hybrid story for mobile app development?
That was when I realized the potential of PWAs ... no more messing around with app stores and the whole packaging and publishing hoopla (although I think that Google still has a "light weight" form of publishing for PWAs, not sure about that).
The fact that you write a web app (PWA) and then you still need to package it inside a native 'shell' (which isn't doing much more than a browser does) always felt somewhat artificial to me, and PWA does away with all that.
The moment PWAs really take off is when I think native app development will begin its downward trajectory, for a large part of mobile app development.
(a company like Apple won't like this because it threatens the power they yield via their App Store - so they might try to push back, but they can't forever keep sabotaging PWAs through an undercooked Safari browser)