Flutter vs. React Native – Which is the Best Choice for Your Next App?
Flutter and React Native are the two most popular cross-platform frameworks on the market today that focus on mobile app development and beyond.
Before these frameworks, building an app for both iOS and Android took double the amount of work.
For more than 10 years, Apple and Google have offered native tools and SDKs to build iOS and Android apps. All along, developers had to make the exact same apps in different languages for different platforms. For businesses, this presents a huge cost. And with ever-increasing users’ expectations, more time and money is needed to make apps that stand out, meaning companies can’t afford to spend precious time rebuilding their app for each platform.
Flutter and React Native change this by enabling developers to write apps with a single codebase and run them on multiple platforms.
And while neither framework is a silver bullet, many teams have used them to reduce the time-to-market for their apps.
This article offers an in-depth comparison of Flutter vs. React Native. This will help you understand their pros and cons and clarify when to use one or the other.
Flutter vs. React Native: the origins
Flutter, created by Google, was first announced in 2017. React Native started at Facebook and was open-sourced in 2015.
Both are very popular today. While React Native is more mature and has a large community, Flutter has been growing faster and recently overtook React Native in search trends and GitHub stars.
So let’s take a deep dive and learn about these technologies in detail.
Programming language: Dart vs. JavaScript
Flutter uses Dart, while React Native uses JavaScript.
JavaScript
JavaScript is a hugely popular language. It is used by nearly all websites today and is the dominant language for server-side programming (thanks to Node.js). JavaScript is the “lingua-franca” of the modern web and powers a vast ecosystem.
React Native builds on this strength by using a language that is already familiar to many. In fact, web developers who are already familiar with React tend to have an easy time learning React Native.
Dart
Dart was introduced in 2011 but has only risen to popularity since Google made their announcement for Flutter. It is evolving rapidly, and according to GitHub, the fastest-growing language in 2019.
Dart is an easy language to learn and shares many traits with other popular languages such as Swift and Kotlin. If you are already familiar with other languages, you can likely become productive with Dart in a matter of weeks.
System architecture
The biggest difference between Flutter vs. React Native lies in their architecture.
Flutter architecture
Flutter uses its own rendering engine called Skia. This is written in C/C++ and provides low-level APIs for rendering, text layout, and more. When you write Flutter apps, your code doesn’t directly call the Flutter engine APIs. Rather, it uses a set of high-level APIs provided by the Flutter framework.
By design, Flutter controls every single pixel that users draw on screen. The Flutter framework offers a rich set of UI components (called widgets) that closely match the native user interface (UI) controls on iOS and Android.
By using Dart, you can compile Flutter apps to fast native code that runs smoothly on all devices.
React Native architecture
In contrast to Flutter, React Native apps draw content on screen using the native iOS and Android UI controls.
This is made possible by the React Native realm, which interacts with the native platform controls.
As a developer, you write shared logic and UI code in the JavaScript realm, and the two realms can communicate with each other across the so-called JavaScript bridge.
This open architecture is very flexible and makes it possible to target more platforms in addition to Android and iOS.
But the JavaScript bridge becomes a performance bottleneck with applications that need to update the UI frequently, as is the case when performing animations.
In practice, this makes Flutter much better suited for building UI-heavy applications that need smooth animations.
UI rendering
Both Flutter and React Native build apps that look and feel native, but they do so in very different ways. Flutter apps are made with so-called widgets, while React Native uses native components from iOS and Android.
Flutter widgets
Flutter widgets are high-fidelity replicas of all the UI components found on iOS and Android.
These widgets closely follow the Material Design guidelines on Android and the Cupertino design specifications on iOS. As a result, Flutter apps look and feel native on each platform without extra developer effort.
Widgets are created with Dart code, just like everything else in your Flutter apps. You can customize the existing widgets or build your own and deliver a completely custom experience that delights your users.
React Native components
React Native uses the actual native components provided by iOS and Android.
You can use them directly in your JS code and customize their appearance with CSS-like style-sheets.
For example, this code defines a button that shows an alert when pressed:
import React from 'react';
// Import any required components from react-native
import {
StyleSheet, Button, View, Alert
} from 'react-native';
// Function for creating the custom button
const AlertButton = () => {
return (
<View style={styles.container}>
<Button
title="Press Me"
onPress={() => Alert.alert('Button Pressed')}
/>
</View>
);
}
// Button styling
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F44336',
alignItems: 'center',
justifyContent: 'center',
},
});
export default AlertButton;
The code above uses JSX, a JavaScript syntax extension to describe the UI in an XML-like format.
The same component can be defined as a widget class in Flutter:
// Import required Material widgets from this file
import 'package:flutter/material.dart';
// Class that defines the custom button
class AlertButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlatButton(
color: Colors.red,
child: Text('Press me'),
onPressed: () => showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: Text('Button Pressed'),
actions: <Widget>[
FlatButton(
child: Text('OK'),
onPressed: () => Navigator.of(context).pop(true),
),
],
),
),
);
}
}
While there are many syntax differences between Flutter and React Native, both frameworks use a declarative programming style for building UIs. The same approach is also shared by SwiftUI, which was launched by Apple in 2019.
Developer experience
Both Flutter and React Native offer a hot-reload feature that allows you to change your application’s code and immediately see the result.
This brings a huge productivity boost for Flutter and React Native developers, as the hot-reload feature is not available when developing apps with the native iOS and Android SDK (though SwiftUI now also offers this feature).
Beyond hot-reload, you can use both Flutter and React Native with the most popular text editors and IDEs. Beginners can get started with Flutter using Dartpad, an online editor for quick prototyping; a similar tool is available for React Native.
Both React Native and Flutter have extensive documentation, covering everything you need to get started. Flutter even has a collection of official YouTube videos showing you how to use the various widgets in practice.
Community and ecosystem
React Native has been around longer and currently has a bigger community than Flutter. Most of the common issues in React Native app development have already been answered on StackOverflow. Because React Native is part of the JavaScript ecosystem, help is readily available.
Likewise, React Native offers many libraries and packages to solve the most common tasks. These can be discovered and installed using the Node Package Manager (NPM).
While the Flutter ecosystem is smaller, it is expanding rapidly and has a very enthusiastic community. Flutter packages are listed on pub.dev (the equivalent of NPM for Dart). Flutter is growing faster and has better maintainer support than React Native.
Because both ecosystems have great documentation and a very supportive community, you won’t feel lost when you get started with either framework.
Package management
Both React Native and Flutter face some challenges with package management.
React Native
Importing React Native packages from NPM often results in the installation of hundreds of dependencies. That’s because the core React Native package itself doesn’t include much of the functionality you need to build apps.
Conflicting dependency versions and frequent breaking changes make React Native very vulnerable to maintenance and upgrading issues.
Flutter
In contrast to this, Flutter offers much more functionality out of the box. You may encounter dependency problems with Dart packages that depend on the corresponding iOS and Android libraries. But the recent Dart tooling improvements make it much easier to resolve these problems.
A bigger issue is that some essential Flutter packages are still immature and not ready for production use. These include camera input, video playback, and ad support. The Flutter team is aware of this and is taking steps to improve the quality of the official packages.
Dependency and package issues are common to all cross-platform frameworks. When you start a new project with Flutter or React Native, you should evaluate what packages you need and see if they are suitable for your app.
Building complex apps
Thanks to the extensive documentation and guides, you can get up to speed quickly both with React Native and Flutter.
But how does the learning curve compare when you want to build more complex or very polished mobile apps?
React Native comes extremely close to delivering a high-quality native user experience. But in practice, the JavaScript bridge can cause performance problems, especially with apps that require a lot of animations or frequent UI updates.
Flutter doesn’t have this problem. In fact, Flutter offers well-designed animation APIs that make it easy to implement complex animations.
Large applications will also need a robust state management solution. Popular state management packages such as Redux, MobX, and Hooks are available both for Flutter and React Native.
Testing
If you want to build robust, production-ready mobile apps, writing tests is paramount. Both React Native and Flutter offer capabilities to write unit tests.
Flutter really shines when it comes to testing. You can test your UI with widget tests that run very fast, and integration tests are supported as well. This makes it easier to create an entire test suite using the official Flutter tooling.
In turn, this vastly reduces the quality assurance (QA) effort needed to test your Flutter apps on multiple devices.
React Native pales in comparison, as it has no official support for writing complex UI and integration tests, and other third-party tools are required instead.
Web support
While both Flutter and React Native started as mobile-first solutions, they can also target the web in addition to Android and iOS.
React Native for the web
React Native itself is heavily inspired by React, the leading JavaScript library for building user interfaces on the web.
React Native developers can use React Native for Web to port their mobile apps to the web, sharing the same codebase.
This is a big win because the same business logic can be shared across all three major platforms (iOS, Android, and web). While web apps don’t have the same capabilities that are offered by the native SDKs, React Native for Web is good enough for many kinds of apps.
Flutter web
Flutter announced web support in beta in 2019, but it faces some big challenges on this platform.
The first one is app size. When you build a Flutter app for the web, the Dart code is compiled into HTML, CSS, and JavaScript code that can run on the browser. But the resulting app size can be much bigger than a regular web app.
The other problem is performance. Flutter web apps suffer from scrolling performance issues. The Flutter team has been working hard on this and has recently introduced a new web compiler that uses Web Assembly (WASM). This improves performance but also increases the app size considerably.
These two problems alone mean that Flutter web is not yet suitable for many kinds of web apps. However, it is a good solution for some very specific use cases. For example, if your Flutter app uses a backend service such as Firebase, it is easy to build an admin web dashboard that connects to the same backend.
If you want to reuse your Dart code on the web, Angular Dart is a viable alternative to Flutter web.
The overall goal with Flutter is to be a unified UI toolkit on all major platforms. Beyond iOS, Android, and web, Flutter is also available on macOS, Windows, and Linux (as an alpha release as of December 2020).
Summary of pros and cons
Now that we have compared Flutter and React Native in detail let’s summarize their pros and cons.
Flutter pros
- High-quality UI: the best solution for building high-quality iOS and Android mobile apps from a single codebase
- Look and feel: easy to adopt platform-specific behaviors and conventions
- Animations: easy to implement complex animations
- Testing: great testing support means that QA effort is considerably reduced
- Faster time-to-market: due to hot-reload feature and a better developer experience
- Documentation: great and comprehensive documentation
Flutter cons
- Flutter web app size and performance: Flutter web is not production-ready due to performance and size problems
- Some immature packages: outstanding issues with some important packages (camera, audio/video, and ad support)
React Native pros
- JavaScript: part of the JavaScript ecosystem
- Native and web: can be used to build production-ready native and web apps with a single codebase
- Documentation: great and comprehensive documentation
React Native cons
- Performance: not ideal for apps with complex animations, frequent UI updates, or intensive computations
- Limited testing support: only basic unit testing support is available
- High maintenance cost: due to breaking changes and too many dependencies
When to use Flutter
Use Flutter if:
- you want to build a high-quality, mobile-first app from a single codebase. Thanks to hot-reload and the great developer experience, you can do so in record time.
- you want to build a very custom UI, or if you have a lot of animations. Flutter makes it easier to translate great designs into code.
Don’t use Flutter if you need a web-first experience, and mobile is not essential to your strategy.
When to use React Native
Use React Native if:
- you want to build simple cross-platform apps on mobile and web with a single codebase.
- you want to build apps using the native components on iOS and Android.
- you’re already familiar with JavaScript and React.js, and you don’t want to learn a new language.
Don’t use React Native if your app needs custom UI and animations or requires regular updates.
Conclusion
Both Flutter and React Native are robust frameworks for cross-platform development, used in production by large companies, and both can reduce the time-to-market for your mobile apps.
Neither is a silver bullet, and every app has different requirements. This means that in some cases Flutter will be the best option while React Native will work better for other projects. I hope this article has helped you decide what’s best for you and your next project.
If you’re just getting started, both Flutter and React Native have great documentation, active community channels, and online courses.
And they are fun to learn! So why not give them a try?
Recommended Articles
Top courses in Google Flutter
Google Flutter students also learn
Empower your team. Lead the industry.
Get a subscription to a library of online courses and digital learning tools for your organization with Udemy Business.