Making the move to mobile
It’s a fact. More people are using mobile devices than conventional desktops. Some companies are late to the game and others are looking to level up to meet and exceed user expectations. In either case, as you consider making an investment in mobile development, it's important to weigh the options and choose an implementation path that meets your needs. With two major mobile operating systems on the market, Google’s Android and Apple’s iOS, most companies are looking for a solution that serves users of both platforms. For best performance overall, native development is still the clear leader. However, choosing native commits you to 2x development costs before you launch and the burden of maintaining two unique code bases throughout the lifetime of your application.
Cross-platform development solutions were created to help manage this burden. The most popular cross-platform development option is React Native (built by Facebook), and now there is a new kid on the block Flutter (built by Google). While Flutter is not yet as mature, our early trials suggest it has great potential.
Exploring React Native vs. Flutter
To get to know this new mobile implementation option, several engineers at Devbridge were asked to experiment with Flutter. In our first experiment, we set the following conditions:
- 1 week of development
- A developer who was new to both ReactNative and Flutter
- Build the same application, with the same design on each framework
In this blog, we’ll walk you through the details of our findings. For a high-level view comparing these two frameworks, see the chart below.
React Native render
A brief history
In 2013, React Native began as an internal hackathon project within Facebook. Then, in 2015, it was offered to the public. Since its official release, React Native has been widely adopted and is still used by the creators at Facebook.
At a Dart Developer Summit in 2015, Flutter was first introduced under a codename Sky. The product demonstrated an impressive 120 fps rendering on Android OS. Using React as an inspiration, Flutter shares some of its DNA with the now competing framework. In December 2018, Flutter version 1.0 was officially released to the public.
The main event
Let’s breakdown how React Native and Flutter compare in the following categories:
- Development environment
- Testing and debugging
- Package management
In the battle for mobile dev domination, who will win the title of Cross-Platform Development Champion?
Winner: Tie [Score=R: 0 – F: 0]
Regardless of which platform you choose for development, the end product is a mobile application, so deployments are not much different from any other native or hybrid application. It is pretty much the same story on any framework if you are working on MacOS. For Windows, however, there are hurdles with iOS in terms of compiling and getting the app on the App Store, so additional tools are required.
React Native has a third-party tool called Expo, which assists developers with app testing, debugging, and deployment. It does make the deployment process more consistent between iOS and Android, and it also allows Windows users to test and publish iOS apps.
Flutter has a few supported options analogous to Expo for app deployment and CI/CD: a tool called Fastlane https://docs.fastlane.tools/, which is referenced in Flutter documentation, and another one called Code Magic, which was proudly announced in Flutter 1.0 release event https://codemagic.io/.
Winner: React Native [Score: R/1 – F/0]
The plugins used most often for accessing hardware resources, managing API calls, and other uses are available on both frameworks. React Native has some out-of-the-box coverage for hardware components, as well as others that are provided by the community. Simply because React Native has been around longer, it has more plugins ready to go. With the vastly larger packages library, React Native takes this round.
On the other hand, The Flutter team provides plugins that connect to all mobile hardware resources.
Honorable mention goes to Flutter for a dedicated plugin library website, https://pub.dartlang.org/flutter, which is well-organized and easy to search. (Although there is an alternative in the React Native realm, https://native.directory/, not all of the plugins are listed, and most of them still live inside the npm directory.)
Winner: Flutter [Score: R/1 – F/1]
React Native does not have any explicit documented support for any dedicated code editor.
I must say that testing and debugging was a bit more enjoyable and robust on Flutter for me. Error messages were easier to read, and it was easier to pinpoint their origin. The Flutter team also prepares development tools well, and there is a pretty robust plugin for Visual Studio Code, as well as extensive support on Android Studio.
Winner: Tie [Score: R/1 – F/1]
There are a lot of similarities between the two frameworks. Neither of them imposes a strict project structure, which means you can organize files however you like. In React Native, almost everything is a component, and in Flutter, they just use a different name for it (a widget). When comparing components vs. widgets, you’ll find they both pretty much mean the same thing.
Another thing to keep in mind is styling UI components. In React, you can use the same styling attributes on every UI component in the React Native library. By comparison, in Flutter, every natively provided widget has its own attributes and is intended to be used for specific instances. Therefore, the Flutter widget gallery is your best friend: https://flutter.io/docs/development/ui/widgets.
Honorable mention goes to Flutter for their team’s support of a dedicated development environment. The contextual assistance built into the Android Studio and Visual Studio Code was very helpful and saved me time on many occasions. You don't need to look up these properties online:
The best alternative for React Native is snippet libraries, which are far from contextual.
Testing and debugging
Winner: React Native [Score: R/2 – F/1]
Because of Apple’s restrictions to only compile iOS apps on a Mac, there are some hurdles for those who are not Mac users. React Native’s tool Expo enables testing on iOS devices using Windows or Linux. Right now, Flutter does not have a solution to compile your app to an iOS device on Windows or Linux.
Winner: Flutter [Score: R/2 – F/2]
React Native has a big community to help you use it and to improve it, but because of the platform’s age, a lot of documentation has not been updated in a while. The React Native homepage is not easy to navigate for a newcomer, and third-party packages usually lack some core instruction for making the package work, forcing you to search for the solution elsewhere. A core problem for beginners with React Native is that all the documentation assumes you already know React JS. A lot of the concepts are similar, but not all of them translate evenly between React JS and React Native. The documentation for React Native is poorly written, to say the least.
Flutter is a whole different story. Maybe because it is still new and growing, most of the documentation is has not aged. The homepage is easy to navigate, and it is also easy to search for packages. Almost every bit of documentation contains a graphic to illustrate the end result, and an example code is in a full-scope view. If you would just have a look at https://flutter.io/, you will see how much it emphasizes beautiful UI examples.
Here’s what React Native’s page looks like: https://facebook.github.io/react-native/
You are greeted with a bland website and a code snippet without any indication of how it should look – unless you are a React guru.
Winner: Flutter [Score: R/2 – F/3]
Here’s where the two frameworks part ways in our competition. Because most of the logic code in React Native is written in JS (and for all we know, Android and iOS are not written in JS), it uses a bridge for the JS components to manipulate actual native components within Android and iOS. This is a good choice if you want to create a fully native feeling experience on each platform. However, if the goal is to make the apps look the same, then that will require a lot of conditional code for separate platforms to achieve visual integrity.
Flutter does not use native components, and it is not a web view either. Flutter draws its own UI, using hardware-accelerated graphics, which feel natively fast. Flutter also has Material and Cupertino libraries, which mimic the native UI language of Android and iOS. The reality is that these components feel just like the real thing. The fact that Flutter is drawing its own UI makes it a lot easier to create a more consistent experience on both platforms without any conditional coding:
Winner: Flutter [Score: R/2 – F/4]
With React Native using npm install or yarn add, for the most part, you’re good to go. However, if the package is using a hardware resource, an additional command in the React Native link is required (although most documentations also mention manual package linking for editing native iOS and Android code). Sometimes a manual intervention is inevitable to make the package work, and usually, you will have to find that on your own, or at Stack Overflow.
Flutter packages are easier to maintain, and all you need to do is add a line with the package name and version to the pubspec.yaml file.
And that is pretty much it on Flutter: No more hidden instructions, apart from adding permission requests to info.plist (iOS) and AndroidManifest.xml (Android).
Taking the dev team’s experience into consideration
You could technically achieve the same or a similar result by choosing either of the two platforms. One key differentiator comes down to the development team’s expertise.
If the development team is experienced with React JS…It would be a no-brainer to start your next project with the Facebook platform. Why? Because React Native is heavily based on React JS, and there are already plenty of React JS developers around.
If the development team is not fluent in React JS…Flutter is the better option. The fluent and visual documentation will get you up and running quite fast. The fear of Dart language should not be an issue. Developer tools are very helpful in suggesting the method that you are looking for as you type. Error messages are usually easy to understand, and it’s easy to pinpoint the source of the problem. (Remember, this is coming from a front-end developer, who mostly works with HTML and CSS.)
The Cross-Platform Development Champion: Flutter
In this battle, the clear winner is Flutter. This new kid knocked out React Native in 4 categories. The breakdown of each round…
- Tie: Deployment
- React Native: Plugins
- Flutter: Development environment
- Tie: Development
- React Native: Testing and debugging
- Flutter: Documentation
- Flutter: Rendering
- Flutter: Package management
One final factor in favor of Flutter: Google seems to care a lot more about the development cycle and is supportive of a lot of out-of-the-box solutions for developers that look and feel robust. (Conversely, React Native is mostly maintained by the community, which creates a problem that there is no one source of truth when looking for guidance on how a developer should use the framework.)
Sharing trade secrets: A rumor in the developer community that is getting more traction says that Google is working on a new mobile OS called Fuchsia (if you go to fuchsia.com, you will be redirected to google.com). It is also rumored that the new OS will be using Dart as its native language, with Flutter as its supported development framework.