A Native iOS Developer's Perspective on React Native vs. Flutter (Part 2)
My experience with Flutter. Overview and initial impressions.
The third and final part of the "A Native Developer's Perspective on React Native vs. Flutter" article series.
Now I’d like to compare some aspects of React Native and Flutter platforms based on my personal experience.
On the React Native side, there’s JavaScript which is extremely popular and has many developers on its side. This may be an obvious win for a lot companies already using this language. Personally, I don't like JavaScript as a language, even in combination with the Flow type checker. Despite the assumption that my experience with TypeScript may be a bit better, this language isn’t for me.
Flutter, however, uses the less popular Dart language. The most noticeable problem I’ve faced with the language itself is that you have to use code generating libraries for your JSON serialisation logic. The language itself doesn’t allow you to deal with this in any meaningful way. It's impossible to inherit your objects from a base class or anything like this for serialisation purposes. The reason for this is that there’s no such thing as returning Self type from a function. Absence of Reflections. You also cannot instantiate an object by its type. Even with these issues in mind, this language is much more appealing to me than JavaScript.
Both frameworks use modern reactive programming idiom for declarative UI. Since both Android and iOS recently introduced their own reactive frameworks, this is obviously our future.
Both frameworks provide you with quite similar development experience. Both have hot reload. The interface layout paradigm and architecture solutions are also comparable. I’d say that you’ll have about the same development velocity with any of those. It feels like the development itself takes less time than I’d do it natively, thus resulting in two platforms instead of one.
This is the most distinctive aspect of these frameworks. As mentioned before, the way these frameworks work and render their UI components is completely opposite. Flutter uses an internal rendering mechanism like Unity or Qt. It renders all its widgets itself but only utilizes the components provided by the Flutter platform or third parties. There’s a way to employ native components, but this isn’t something you normally do. In contrast, React Native wraps native components: in this case, you end up using real native components, rather than faking them.
Besides, Flutter introduces a risk of being dependent on Google to update this framework for each version of the mobile OS. This re-implementation of the user interface can also be beneficial. Applications that use the same user interface on both platforms will have a big win here. This means that you’ll only need to write the UI components once, and they’ll be identical on both platforms. As of today, Flutter provides a significant number of components out of the box, much more than React Native has. As a result, it’s unlikely that you’ll feel the need for any third-party components at all.
To conclude, React Native may be the better choice if you want your application to look as native as possible. Flutter, on the other hand, will be the better option for applications with custom user interface and complex animations.
This is an area where React Native is currently ahead due to the age of the platform itself and the ability to use JavaScript libraries. I wouldn’t consider this aspect for my application unless there was a core technology that wasn’t available for one of these platforms.
From my personal experience, Flutter is a clear winner. I can't remember a single time I've debugged some of the mystical bugs that happened to me with React Native. One of the issues with the React Native is the language itself, which is untyped. As opposite, Dart is a typed language that gives you much less freedom to do something wrong and prevents most of the runtime crashes.
Google has done a great job of creating comprehensive documentation for Flutter. Even at this stage, when the Flutter is still quite young, the documentation is noticeably better and more detailed than what’s currently available on the React Native side.
In my case, Flutter was a much more performant solution than React Native and considerably more straightforward in terms of multithreading. The problem with React Native is that it must bridge your JavaScript code to the native counterpart and is unable to compile this code natively. This isn’t such a critical factor though, as all these problems can be overcome by implementing some performance sensitive parts on the native side.
You can love or hate them, but this is a critical aspect of any framework meant to be used in production. In any front-end development, there are two kinds of testing involved: classical unit testing and UI testing. The unit-testing part is rather trivial on any platform, and these are no exception. We’ve a nice set of tools on the side of React Native, like Jest, and quite sophisticated tools on the Flutter side.
Now let's talk about testing the user interface. There’s no official support for user interface testing on the React Native platform. Yet, not everything is hopeless, since there are third party solutions for this. We can write a user interface test using Appium's universal multi-platform solution and more React Native oriented solution Detox.
On the other hand, Flutter provides an official user interface testing environment. It can even perform user interface testing at unit testing speed.
The Flutter command line interface allows you to perform the entire build and deployment process. However, this isn’t the case with React Native. On the React Native side, you have to use Xcode and Android Studio to deploy your application. Even though there are some problems with React Native in this area, you’ll probably still be using Fastlane for both of these frameworks. The reason for this is that you’re likely to encounter more complex deployment scenarios than just building the app.
From the CI's point of view, you can find many services that support both of these frameworks. I personally stick to Bitrise as the most complete solution in my opinion. There’s even a special service for Flutter applications called CodeMagic. It just isn’t universal enough for me as I have many other projects.
For my personal needs, Flutter is a clear winner, but that doesn't mean it should be the same for you.
There are some areas where you should consider falling back to native development: for example, if your app has a simple UI but heavily relies on system APIs such as Bluetooth or own hardware. Native development will always win in terms of application size. We’re talking here about roughly 10 MB overhead which isn’t that crucial presently. Energy efficiency can also be considered as a criterion for picking the native approach. Applications focused on widgets, watches, and TVs, aren’t the best fit there either. And, of course, if you have a budget and want to get a project of the highest possible quality, native development is clearly the way to go. This isn’t the case for my personal projects within very limited resources, though.
As for React Native, it's better for those who are looking for a real native UI and UX but want to share their codebase. In this case everything will always be in sync with the latest operating system updates. Another aspect is that React itself and JavaScript are very popular technologies in Web development these days. It makes sense to stick to the same stack of technologies that are already used in your company and has existing codebase.
Another factor to keep in mind is that both React Native and Flutter promise to easily port your application to the web, which isn’t the case for the native development.
Lastly, from a product point of view, both of these technologies make it easy to keep most of your features and, of course, the bugs aligned between the two platforms.
As you may have noticed, I've encountered a lot of trouble with React Native. But even with all these issues, I managed to achieve my goal and release the Android version of my application.
Experience with these frameworks has completely changed my opinion about cross-platform development. I no longer think of it as a bunch of web views instead of a real app. Overall, I had a great time using both frameworks. From my personal experience, Flutter beats React Native in almost every aspect. As of today I’ve already finished several commercial projects using Flutter technology without any major issues.
The world of cross-platform development has changed forever. Of course, there are still projects where, as I mentioned earlier, you’ll benefit immensely from native development.
As for me, I'm still doing commercial development of native iOS applications as well as Flutter. For all my personal projects, however, I plan to stick to Flutter from now on. I honestly believe this is a more cost-effective technology for me. I’m happy that I’ve found time to study both technologies and obtain a good technological pool to choose from accordingly.
My experience with Flutter. Overview and initial impressions.
The reason I've decided to look into the cross-platform development and my first React Native experience.