Flutter tutorials and courses by Andrea Bizzotto

Flutter vs React Native - Which is the Best Choice for Your Next App?

This article was originally posted on Udemy’s Blog: Flutter vs React Native - Which is the Best Choice for Your Next App?.

Focusing on mobile app development and beyond, Flutter and React Native are the two most popular cross-platform frameworks on the market today.

But things weren't always like this.

For over 10 years, Apple and Google have been offering native tools and SDKs to build apps for iOS and Android. All along, developers had to build the exact same apps in different languages for different platforms.

For businesses, this is a huge cost. And with ever-increasing users' expectations, more time and money is needed to make apps that stand out.

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 of them 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 you when to use one or the other.

Flutter vs React Native: the origins

Flutter is made by Google and it was first announced in 2017. React Native started at Facebook and was open-sourced in 2015.

Flutter vs React Native | Google Trends
Flutter vs React Native: interest over time. Source: Google Trends.

Both are very popular today. While React Native is very mature and has a big community, Flutter has been growing faster and recently overtook React Native both 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 it is also a popular language for server-side programming (thanks to Node.js). JavaScript is the "lingua-franca" of the modern web and powers a huge 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 have an easy time learning React Native.

Dart

Dart was introduced in 2011 but has only become popular since Flutter was announced. Dart is evolving rapidly and was ranked as the fastest-growing language in 2019, according to GitHub.

Dart is an easy language to learn and shares many traits with other popular languages such as Swift or Kotlin. If you are already familiar with other languages, you can 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 Architectural Layers
Flutter Architectural Layers. Source: Flutter.dev.

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 call directly 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 is drawn on screen. The Flutter framework offers a rich set of UI components (called widgets) that closely match the native UI controls on iOS and Android.

And by using Dart, Flutter apps can be compiled to fast native code that runs smoothly on all devices.

React Native Architecture

In contrast to Flutter, React Native apps draw content on screen by using the native iOS and Android UI controls.

React Native Architecture

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.

The React Native community is working on a new architecture to address the performance issues with the React Native bridge. This is known as the "TurboModules" feature and you can learn more about it on this page.

UI Rendering

Both Flutter and React Native can be used to build apps that look and feel native, but they do so in very different ways.

Flutter Widgets

Flutter widgets are high-fidelity replicas of all the UI components found on iOS & Android.

Flutter 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 & 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 lets you change your application's code and see the result immediately.

This is a huge productivity boost for Flutter and React Native developers, as hot-reload is not available when developing apps with the native iOS and Android SDK (though SwiftUI now also offers this feature).

Beyond hot-reload, both Flutter and React Native can be used 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 also 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 & Ecosystem

React Native has been around for longer and has a bigger community. Most common issues in React Native app development have already been answered on StackOverflow. Because React Native is part of the JavaScript ecosystem, more 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).

The npm.js and pub.dev package managers
npm.js website (left) - pub.dev website (right)

While the Flutter ecosystem is smaller, it is growing 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.


However, both React Native and Flutter face some challenges with package management.

Importing React Native packages from NPM often results in hundreds of dependencies being installed. That's because the core React Native package itself doesn't include much of the functionality that you need for building apps. Conflicting dependency versions and frequent breaking changes make React Native very vulnerable to maintenance and upgrading issues.

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. Though 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 apps?

React Native comes really 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 apps, writing tests is paramount.

Both React Native and Flutter offer capabilities to write unit tests.

But React Native has no official support for writing complex UI and integration tests, and other 3rd-party tools are required instead.

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.

Web support

While both Flutter and React Native started as mobile-first solutions, they can also target web in addition to Android and iOS.

React Native for Web

React Native itself is heavily inspired by React, the leading JavaScript library for building user interfaces on web.

React Native developers can use React Native for Web to port their mobile applications to 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 & 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 has also 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 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.

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).

Pros and cons

Now that we have compared Flutter and React Native in detail, let's summarize their pros and cons.

React Native and Flutter logos

Flutter Pros

  • High-quality UI: the best solution for building high-quality iOS & Android apps from a single codebase
  • Look and feel: easy do 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 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, ad support)

React Native Pros

  • JavaScript: part of the JavaScript ecosystem
  • Native and web: can be used to build production-ready native & 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: this is 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 & 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 used in production by some large companies.

    Both are robust frameworks for cross-platform development.

    And both can reduce the time-to-market for your mobile apps.

    Neither is a silver bullet and every app has different requirements. 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?

    Want more?

    Fast-track your Flutter learning with over 40 hours of in-depth content.