I'd like to know more from the community
Specific React Native circumstances and design choices, like the coexistence of alternative Javascript interpreters (e.g. JSC and Hermes), different tools for the same purpose (e.g. npm and yarn), separate organizations (e.g. React vs. React Native vs. the "standard library" vs. certain tools) and radically different code styles (e.g. old class components and new function components that are nicer but without feature parity) add risk and pointless maintenance.
I know the title suggests cross-platform frameworks, but let me give my opinion: go native. For Android, Kotlin + Jetpack Compose. For iOS, Swift + SwiftUI.
Now let me elaborate my opinion: Cross-platform doesn't work well across devices types. A desktop screen is fundamentally different from a phone screen (one is a big screen controlled with mouse + keyboard, the other is touch on a small screen). All the cross-platform apps I have seen trying to get both Desktop and mobile are weird in some way, it's the worst of both worlds.
Now let's say you only want to target mobile. Then suddenly it's "some cross-platform framework" vs "2 native apps (iOS + Android)". It may seem like cross-platform means "write once", which would be half the time of writing two apps. But that's not the case. Cross-platform is more "write once, debug everywhere". And debugging is not fun, the fun part is to write the app. Kotlin and Jetpack Compose are super cool, Swift and SwiftUI too. Just choose one, and then if your app needs it, learn the other.
Here are a few problems that I have seen with cross-platform frameworks for mobile dev:
- There are huge communities for Android and iOS. Much better than any cross-platform framework. So you are more likely to get help there. - Cross-platform is annoying: develop for Android, then test on iOS and find bugs. Fix them, test on Android and find that your fixes just broke Android. Fix that, and go back testing for iOS. - Cross-platform is a tradeoff: either you have to use what's exactly common between Android/iOS, or you have to do some kind of `if (android) elseif (iOS)` (which sucks).
It's a pretty cohesive ecosystem, all the build tooling, the package manager, etc comes with the project.
There's relatively little learning of "best practices" because there is mostly one way to do stuff.
People might disagree with me but I find dart a very nice language, feels like more sleek simpler modern Java. Also there is no awkward language conversion with Typescript / Javascript.
Lastly the "Reactive UI" philosophy is pretty similar across the front end frameworks you mentioned.
I haven't used Flutter professionally yet, but, I very much enjoy using it for my personal projects.
I understand what RN/Flutter are trying to do but in my opinion it’s a pain to maintain and there are just too many layers that can rot out from under you. Capacitor, on the other hand, is just a bridge from native to JS and your UI is simply HTML/CSS. This also lets your target Web with the same codebase which, while possible in RN/Flutter, is not simple or as maintainable IMHO.
Nothing will beat Swift/Kotlin for platform integration (both in UI and capabilities) but maintaining 2-3 (if you want web as well) codebase is not an easy task for 1 person or even a small team. As far as capabilities, in Capacitor I can also drop down and write native code (it’s 1000x easier than it ever was with Cordova, don’t be scared off if you hated Cordova) if I want so really fully native apps only win on fitting the platform UI better.