Wern Ancheta Fullstack developer, fitness enthusiast, skill toy hobbyist.

React Native Web vs. Flutter web

11 min read 3185

React Native Web vs. Flutter Web

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.

React Native vs. Flutter: Comparing the underlying platforms

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:

Beginner friendliness

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:

  1. Install Node.js
  2. Install Git
  3. Install Watchman (for MacOS users)
  4. Install Expo CLI
  5. Generate a new project
  6. Install Expo client on your mobile device
  7. Run the project

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:

We made a custom demo for .
No really. Click here to check it out.

  1. Download the Flutter SDK
  2. Install the prerequisite developer tools (e.g. curl, zip, git)
  3. Add the Flutter SDK to your system path
  4. Install Android Studio and Xcode
  5. Configure XCode command line tools (for MacOS)
  6. Generate a new project
  7. Run the project

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.

Community

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.

However, React Native is a more popular option for web developers coming to mobile development because it uses JavaScript and a subset of CSS for styling apps.

Plugin support

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

Developer productivity

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:

  1. Programming language
  2. Documentation
  3. Code structure
  4. Developer tooling
  5. UI components
  6. Native API access

Programming language

To build React Native apps, you need to know how to write JavaScript code. While in Flutter, you need to know Dart.

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.

Documentation

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.

Code structure

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.

Developer tooling

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.

UI components

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.

Native API access

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

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.

However, when it comes to pure code performance, Flutter is the clear winner because the code that you write is compiled directly into native code. Unlike React Native, Flutter doesn’t have the concept of a “JavaScript bridge” for passing data between the JavaScript side and the native side of things. React Native’s “bridge” itself may soon be replaced by JSI.

Web support

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.

Testing and deployment

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.

When it comes to provisioning and deployment, there’s fastlane, App Center, codemagicBitrise, and Expo’s EAS build.

On the other hand, Flutter has built-in testing support (unit, widget, and integration). For deployment, it can be used with fastlane, Bitrise, Cirrus CI, Appcircle, and codemagic as well.

Flutter web overview

Flutter web is an implementation of Flutter that allows you to compile the Dart code you use for building Flutter apps into HTML, CSS, and JavaScript code.

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.

Why is Flutter web good?

  • It’s stable and production-ready
  • The feature set is complete and enables developers to build rich, interactive web experiences
  • Access to the same widgets that are available for Flutter for mobile
  • Full access to all existing Dart libraries that run on the web
  • Integration with IDEs and text editors (IntelliJ, VS Code)

Why is Flutter web bad?

  • Large download size if you use CanvasKit as the renderer
  • Not all JavaScript libraries are supported. It only supports Dart’s JS-interop packages
  • Not SEO friendly
  • Currently more suited for progressive web apps and games rather than typical websites

React Native for Web overview

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 <div>, the <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:

  1. Just like how there are platform differences between Android and iOS, the same is also true for the web. This means that your existing React Native code won’t immediately run on the web just by using React Native for Web. You still have to do a lot of platform detection and code modification. This is especially true for things like the file system.
  2. Not all APIs that are available in React Native are available in the browser. This means that if you have an existing React Native app, you either have to re-implement the functionality on your own or simply not support it at all when on the web. An example of this API issue is the Image Editor.
  3. Not all components that are built into React Native or Expo work on the web. An example of this is the Modal component. Sometimes there’s another developer who would publish their own version of the component that can run on the web, but in cases where that’s not available, then you have to build your own component. The same thing is true for libraries; the authors will have to write their own implementation for the web.

Why is React Native for Web good?

  • Just like React Native, React Native for Web includes tools that allow developers to build accessible apps. This is provided through accessibility props such as accessibilityLabel and accessibilityRole
  • Allows for executing web-specific code via platform detection. We can’t expect all the APIs to work, thus it’s very important to detect the platform so that you only execute code that works for the current platform
  • Support for server-side rendering. You can use AppRegistry to hard-code the HTML document string to be used for rendering the app
  • Expo Web serves as a wrapper for React Native Web so you can start a single Expo project that can be run on Android, iOS, web, and even desktop (through Electron)
  • Expo web supports progressive web apps

Why is React Native for Web bad?

  • At the time of writing this article, React Native for Web is still not production-ready
  • React Native packages with native dependencies cannot be run on the web. If you’re relying on third-party packages with native dependencies (Swift/Objective-C or Java/Kotlin code), then those won’t work on the web
  • React Native packages with no native dependencies cannot be expected to work 100 percent either. This is especially true if it involves animations, transitions, gestures, the keyboard, and lists

Flutter pros and cons

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:

Why is Flutter good?

  • Performance is very close to native because your code compiles to native code
  • Lots of inbuilt widgets for both Material Design and Cupertino
  • Inbuilt testing support
  • Detailed and well-organized documentation

Why is Flutter bad?

  • Error messages are more meaningful because Dart is strongly typed
  • Slightly steep learning curve

React Native pros and cons

Let’s now go over the pros and cons for React Native:

Why is React Native good?

  • Beginner-friendly
  • Has access to the JavaScript ecosystem via npm modules

Why is React Native bad?

  • Slower hot reloading on Expo when compared to a standard React Native project
  • Documentation is sparse and not very detailed
  • Limited native UI components
  • It doesn’t have an official testing utility

Which is better: Flutter web or React Native for Web?

Just like every argument as to what’s the best platform for your next project, there’s no right or wrong answer. It depends on various factors that mostly boil down to your project’s performance needs and the relevant experience of your team. Does your project need butter-smooth UI interactions and animations? Does your team have existing experience with JavaScript? Are you willing to explore and use third-party solutions not provided by the core platform itself?

When it comes to web capabilities, I’d say that React Native for Web is production-ready depending on your needs. It stays more true to the technologies that make the web work because it simply compiles down to good old HTML, CSS, and JavaScript.

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: Instantly recreate issues in your React Native apps.

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

Wern Ancheta Fullstack developer, fitness enthusiast, skill toy hobbyist.

3 Replies to “React Native Web vs. Flutter web”

  1. “Error messages are more meaningful because Dart is strongly typed” is listed in the Cons section for Flutter but it sounds more like a pro!

  2. A year later, would you say things have changed regaring the maturity of flutter web (actually, of both frameworks)?

Leave a Reply