Editor’s note: This article was updated July 2021 with information about Flutter 2’s web support and an up-to-date comparison for React Native and Flutter. You can learn more about Flutter 2.0 here.
As developers, we are always on the lookout for tools that would allow us to save time and effort. We want to be able to write code and run it everywhere. With React Native and Flutter, this dream is slowly turning into reality. Because now, not only can we run apps on both Android and iOS, we can run them on the web and even desktop as well.
In this article, we’re going to compare each platform. Then we’re going to zoom in on their web capabilities to see if they are good enough to be used in production. Lastly, we’ll look at the pros and cons of each platform. After reading this article, you’ll be able to decide which one to use on your next project.
For us to effectively judge React Native Web and Flutter for web, it’s important that we first compare the underlying platform. We have to consider not just the web capabilities, but also the overall platform experience.
We’ll use the following criteria as the point of comparison:
How quickly can a beginner go from zero knowledge of the platform to a fully functioning app?
In React Native, it’s a multi-step process:
There’s one extra step required to run it on the browser, but that’s negligible because it’s only a command to install the web dependencies.
The steps mentioned above are from the quick start guide. You’ll need to invest more time when setting up your machine if you go the CLI route, though that’s something a beginner rarely needs to do since most of the native APIs are already implemented in Expo.
On the other hand, Flutter’s development setup can be summarized with the following steps:
For the web setup, there are a few additional steps you need to go through.
It looks pretty straightforward, but it can be pretty daunting for a complete beginner with little to no experience of the command line and no understanding of how to install different tools.
The community is another big factor to consider when choosing a platform. This community is the culmination of libraries and plugins, tutorials, forum/Stack Overflow questions, and GitHub issues that are out there.
React Native has more than a two-year head start, but that doesn’t necessarily mean it’s more popular. Flutter has 125k stars on GitHub while React Native sits around 97k. It looks like they’re receiving similar use: both have around 100k questions on Stack Overflow.
In terms of actual usage, according to the Stack Overflow developer survey for 2021, about 15 percent of all respondents are using React Native while about 14 percent are using Flutter.
Web developers are a spoiled bunch. Almost all of the functionality we’re ever gonna need in building modern web applications already has a corresponding library that implements it. All we have to do is learn its API and we’re good to go.
Flutter has a pretty decent plugin system that implements most of the functionality that is commonly used in mobile apps (e.g., social login, Google Maps).
React Native wins this because we can use almost any npm module (except for those node modules with native dependencies).
Another important factor when it comes to deciding which tool to use is developer productivity. This can mean a lot of things, so we’re going to break it down into the following:
Most people coming to explore solutions for building cross-platform apps using a single codebase are web developers. We want to reuse our existing knowledge of the web ecosystem to build mobile and desktop apps. This means that React Native is a more viable option for us since we practically don’t have to learn anything else to build apps using React Native.
Being able to find the things you’re looking for in a relatively short time and immediately grasp the information is another determinant of developer productivity.
Flutter’s documentation is more organized and more detailed than React Native. But when it comes to beginners, it can be pretty overwhelming to be greeted by tons of links. I like the simplicity of React Native’s documentation.
That said, we don’t stay a beginner forever. Once we gain more experience and get used to where things can be found, then it becomes easier. This is where Flutter’s documentation outshines React Native. Furthermore, React Native relies on a lot of community-written libraries, so its documentation is very fragmented. Meanwhile, Flutter has everything in one place.
As a new developer coming into an existing project, how easy is it to make sense of the way the code is organized?
In React Native, you can pretty much have any structure you want. Usually, it’s dependent on the size of the project and the various tools and libraries that your team has adopted. For example, using Redux will force you into a specific kind of structure since you will have reducers, actions, etc.
The situation is the same in Flutter; you can organize your code any way you want. But since navigation and state management are already baked into the framework, code organization can get more opinionated as well.
Hot reload is one of those things that can get annoying if a platform doesn’t support it. Being able to modify your code and see the changes on the fly as you save is a big productivity booster (especially on a dual-monitor setup).
Both React Native and Flutter support this feature, though it’s faster in Flutter if you compare it with Expo. There’s just a tiny bit of difference when compared to the CLI route for React Native.
Another important thing to consider is the debugging experience. In React Native, error messages can be pretty hard to grasp. While in Flutter, due to Dart being a statically typed language, the error messages it shows tend to be more meaningful.
React Native components translate to native UI components, so it has the same look and feel as a native app.
On the other hand, Flutter paints the UI elements using a rendering engine. It’s responsible for creating all the basic functions of each of the widgets. This means that there’s a constant effort on Flutter’s development to match the native UI behavior whenever there’s an update to the respective platform.
React Native only provides a few basic components. Though there are various UI kits available, it still cannot beat the widget collection that’s built into Flutter. The only downside with Flutter is that it has more widgets available for Android compared to iOS.
Both React Native and Flutter support native APIs for commonly used features such as image picker and geolocation. If you need a native functionality that’s not available yet, you can always write custom platform-specific code or create your own native module.
App performance is difficult to judge because it purely depends on what type of app you’re going to build. If your app doesn’t require complex layouts, transitions, and passing data to and from the native side, then you can choose either of the platforms.
Both React Native and Flutter have web support, the former being more of a community-led effort, while the latter is led by the Flutter team.
Web support for React Native is more mature than in Flutter. Web support can be added to existing React Native projects and Flutter projects, though they’re not really comparable. React Native Web compiles to actual HTML elements while Flutter uses the Canvas.
We’ll dive more deeply into web support for each platform later on in this article.
Does the platform support automated testing and deployment (provisioning, continuous integration, and deployment)? This can be optional for smaller projects, but crucial for larger ones. It helps us prevent bugs in our apps and not get bogged down by the manual deployment process.
At the time of writing this article, React Native doesn’t have testing and deployment tools baked into it. Just like for everything else, it relies on the tools built by the community. For testing React Native, we have the React Native Testing Library, Jest, and Detox.
Flutter web works by using web renderers. Simply put, they’re used for rendering a Flutter app on the web. Flutter uses two renderers: the HTML renderer and the CanvasKit renderer. The former uses HTML, CSS, and the Canvas API to produce pages. The latter is basically Skia for the web using WebAssembly and WebGL.
The main advantage of the HTML renderer is its compact size, though its disadvantage is its performance.
On the other hand, CanvasKit offers great performance but it has a poor startup time. This is mainly due to the additional 2Mb download size compared to the HTML renderer.
Users have access to widgets available for mobile. But developers have to consider making their apps responsive. Therefore they have to use widgets and classes such as LayoutBuilder or MediaQuery so that their apps will look great for whichever platform the user is using.
When it comes to plugins, not all of them have web implementation (e.g., ARCore, Filesystem access). In pub.dev, you can filter the results to only show the plugins that are available for the web.
React Native for Web is an open-source project by Nicolas Gallagher. React Native for Web makes it possible for developers to use React Native components and APIs on the web. The clear advantage of this is that it allows for code-sharing between multiple platforms, so you only have to write mostly single code and be able to run it everywhere.
Perhaps one of the first questions that comes to mind when you hear about React Native for Web is why not just use React? The answer to that is code sharing. If you use React, you can’t really take advantage of the tools that React Native has to offer. And you’ll be coding the same functionality twice.
Do note that not all of the native components and APIs are available to the web. This is because not all of them have an equivalent web API. The main thing that React Native for Web does is to map out the web equivalent for each of the React Native components and API. So the
<View> component becomes a
<Image> component becomes
<img>, and so on.
The second question that might come to mind is what’s the difference between React Native for Web and Expo Web? How do I know which one to use? Well, just like how there’s the standard CLI route for React Native projects, there’s also the quick start route, which is Expo.
Expo Web is just a nice addition that you get when you’re already building your projects with Expo. So if you already have an existing project, the main deciding point is whether you’re building your project in the standard CLI way or Expo. However, if your project is new, it will solely depend on what your project is all about. If you think you’re going to need a lot of third-party libraries with native dependencies, then you’re better off sticking to the standard React Native CLI. Otherwise, there’s really no reason not to use Expo since it just makes things that much easier for you.
Developers who plan to use React Native for Web have to worry about the following problems:
AppRegistryto hard-code the HTML document string to be used for rendering the app
To wrap up, let’s take a look at what makes each platform great and not so great. First up is Flutter. Note that we’re not going to go over the good and bad points that are similar between the two platforms. Instead, these points can either make you “yay” or “nay” when it comes to choosing the platform that’s best for you:
Let’s now go over the pros and cons for React Native:
On the other hand, Flutter web is also production-ready depending on your needs. The main issue with it is really the performance. They have solved it using CanvasKit, but the user will have to wait even more to download the necessary scripts.
Overall, it’s an exciting time to be a developer because we can now reach more platforms than ever. All of that without leaving the comfort of the tools we know and love.
LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.
LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.
Start proactively monitoring your React Native apps — try LogRocket for free.
ElectricSQL is a cool piece of software with immense potential. It gives developers the ability to build a true local-first application.
Leptos is an amazing Rust web frontend framework that makes it easier to build scalable, performant apps with beautiful, declarative UIs.
We spoke with Dom about his approach to balancing innovation with handling tech debt and to learn how he stays current with technology.