We are no longer questioning the viability of cross-platform, we are now deciding which solution is best. React Native and Flutter are great options to choose from despite other possible solutions e.g. Xamarin and others.
Flutter in the other hand does not render native widgets. It relies on a rendering engine to paint 2D UI elements. Flutter’s engine, written primarily in C++, provides low-level rendering support using Google’s Skia graphics library². This architecture decision provides Flutter with low-level control of rendering, enabling it thus for possible performance improvements.
Most UI elements will not display much difference when rendered by a rendering engine or the platform’s widgets. The difference is often noticed on elements that interact with Users. The native UI elements usually have unique behaviors on each platform. For example, screen transitions, on iOS the screens slide in, while on Android the slide feels more like a fade-in. Also Text Inputs, these have accessibilities built-in by the platform. The rendering engine has to create all the basic functionalities of the Text Input, copy and paste, the positioning of the cursor, and even displaying the text.
The React Native core team has commented that it was a conscious decision to render native widgets instead of rendering UI elements themselves, according to them, it never seemed like the right approach for the following reasons; They didn’t want to reimplement everything provided by the platform; The amount of work required to reimplement everything and keep up with platform updates, including support to multiple OS looks, both new and old³.
While Flutter, on the other hand, it attempts to provide identical UI look and feel on all platforms, Reflectly, an App which was originally written in React Native, was rewritten in Flutter with this in mind⁴, Flutter enabled Reflectly Development team to write an App on iOS and expect the exact same look and feel on Android.
It is unneglectable the effort of writing a cross-platform solution as Flutter requires more resources than React Native. Flutter is trying to match Native UI widget’s behavior and although they have released a 1.0 version, this is an ongoing work⁵.
When does Developer Experience decide the technology to use on a project? Hopefully, always. Good developer experience enables the Development team to write better Software. It keeps Developers happy. React Native made a big impact on mobile development by introducing hot reload and a declarative UI framework⁶. These two points increased developer productivity and overall happiness.
After developing Mobile Apps for almost 3 years using React Native, using Flutter for the first time left me a great impression. It has done an amazing job at creating a great onboarding experience by providing Flutter Docter, Hot reload, and well documented Docs. It is safe to say that anyone with Mobile development experience can be productive with Flutter exceedingly fast.
The React Native developer experience is an ongoing improvement process. Until last year, the attention given to the open source community and consequently Developer Experience if compared to the efforts given today were smaller. Since the end of last year, React Native’s core team has made perceptible efforts in improving how it interacts with the Open Source community. These efforts can be noted by the "What do you dislike about React Native?" versions 1 and 2. Dan Abramov is currently in charge of revamping the hot reload module⁷ which has been subject to some bugs.
Available UI elements
Both Flutter and React Native provide all the UI elements you need, nonetheless, each has taken a different approach at this. Flutter tries to deliver first class support to all the UI elements you might need, it has a long list of widgets⁷, its goal is essentially for you to not need any third-party integration, it encourages you to write your own Widget. React Native on the other hand, since it is an App rendering Native UI Widgets, it is striving towards a lean core⁹, where React Native will host the minimum set of modules you need, and leave any other dependencies to be managed by third-party open source. With React Native, there is no overhead on integrating native Views or Modules, just the cost of the communication through the bridge which is the reason for an architecture rewrite codenamed fabric¹⁰.
React Native Lean Core strategy to some sounded like a bad idea, removing some of the UI elements from the main repo meant others outside of Facebook would have to step up to contribute. The Lean Core ended up being a positive surprise, All extracted modules have received maintainers and have been updated more than ever.
It is important to note that if your App requires a native UI View integration, Flutter is responsible for all the rendering, therefore, when you need to render a Native UI View, either Android or iOS, it must embed the view in Flutter’s hierarchy. For iOS the Documentation notes that this is an expensive operation¹¹ and I’ll add that for Android it should not be super smooth since embedding views is not straight-forward.
Breaking changes are the main problem when updating. React Native’s longer life has displayed multiple moments of frustration due to updates. This is not unique to React Native, it is rather a Software Development problem. Despite Flutter’s shorter existence, it has already encountered moments where it needed to introduce a breaking change¹³, on a survey by Flutter’s Core team, it questioned its users if breaking changes for a greater good was acceptable¹².
There is evidence that both communities are doing it’s best to solve the updating issues by providing clear documentation and tools to help. Flutter has provided a Github Wiki¹³ for such occasion. While React Native’s Core team and community have created a tool¹⁴ and documentation to deal with this.
Despite Core teams efforts, they are not exempt from the issues caused by targeted platform updates. AndroidX has been the reason for much efforts to correctly adapt to it¹⁵.
If we wrote two apps, one in React Native and another in Flutter with a couple of screens you will not really notice a difference. Only one post that contained benchmarks was found on the internet¹⁶. It was a timer app, by looking at the benchmarks you can see that it displayed a very small difference between a Native Android, Flutter, and React Native. However, this post has a flaw, it did not evaluate the key points where performance really matters, which are Animation and large lists.
Even with the possible improvement to animations with React Native, you can’t deny the fact that Flutter is using Skia as a rendering engine. This is a very performant framework and in Flutter’s release, it displayed the capability of rendering 120 FPS on an Android device.
With lists, Flutter also does an amazing job by providing an out of the box API specifically for large lists. ListView.builder delivers virtualization out of the box with really high performance. On React Native, you can achieve acceptable performance with FlatList, however, it requires some tweaking as you can see on the Optimizing Flatlist Configuration post.
Flutter and React Native are great tools for cross-platform development. Either one will deliver a high-quality Application.
 Wikipedia contributors. (2019, June 30). Flutter (software). In Wikipedia, The Free Encyclopedia. Retrieved 14:04, July 7, 2019, from https://en.wikipedia.org/w/index.php?title=Flutter_(software)&oldid=904189137
 Reactiflux QA React Core Team. (2019, January 24). In reactiflux.com transcript, retrieved from https://www.reactiflux.com/transcripts/react-native-team/#youitv-engine-one-currently-binds
 Reflectly App presentation. (2019, Mar 7). In Mobile World Congress 19, retrieved from https://youtu.be/hdOxvNQbies?t=746
 On July 7th, 2019, we can find the following issues in Flutter’s repository related to UI elements behavior which would not exist if they were using Native UI Widgets: https://github.com/flutter/flutter/issues/35068, https://github.com/flutter/flutter/issues/35577, https://github.com/flutter/flutter/issues/35694. There are more this is just an example.
 We can see the evidence of this impact by the number of declarative mobile frameworks/toolkits which came after React Native. Flutter, SwiftUI, Jetpack Compose
 Widget index https://flutter.dev/docs/reference/widgets
 Ticket related to the broken hot reloading module https://github.com/facebook/react-native/issues/18899
 Ticket related to Lean Core https://github.com/facebook/react-native/issues/23313
 This is a good overview of the current bridge architecture, https://hackernoon.com/understanding-react-native-bridge-concept-e9526066ddb8. Issue corresponding the Fabric architecture https://github.com/react-native-community/discussions-and-proposals/issues/4.
 Embedding iOS views is an expensive operation and should be avoided when a Flutter equivalent is possible. https://api.flutter.dev/flutter/widgets/UiKitView-class.html
 Insights from Flutter’s first user survey of 2019. (2019, April 11). In Medium post, retrieved from https://medium.com/flutter/insights-from-flutters-first-user-survey-of-2019–3659b02303a5
 Flutter’s Handling breaking changes Wiki https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
 React Native’s Upgreade Helper https://github.com/react-native-community/upgrade-helper
 Flutter and React Native’s evidence of AndroidX support efforts. https://flutter.dev/docs/development/packages-and-plugins/androidx-compatibilityhttps://github.com/react-native-community/discussions-and-proposals/issues/129
 Alex Sulivan - Examining performance differences between Native, Flutter, and React Native mobile development. Thoughtbot dev site: https://thoughtbot.com/blog/examining-performance-differences-between-native-flutter-and-react-native-mobile-development
 Various posts complaing of Animated performance: https://www.reddit.com/r/reactnative/comments/6ex9y1/brutally_slow_animations_on_android/, https://stackoverflow.com/questions/48928229/slow-animations-in-reactnatives-android-app
 react-native-reanimated https://github.com/kmagiera/react-native-reanimated
 React Native Repository Pull Requests from Amazon, Callstack, and Expo