Back

React Native vs. Flutter

React Native vs. Flutter

When there is a need to develop a mobile app these days – there are plenty of technologies to choose from, ranging from classic native Android or iOS applications to a variety of cross-platform frameworks. With the high popularity of Flutter and React Native cross-platform frameworks, let’s compare several important technical aspects of these frameworks, which might help when choosing one.

Writing Code

React Native uses JavaScript (JS)/TypeScript (TS) with the React framework, while Flutter utilizes Dart, a newer language than JS.

JS/TS and React are popular choices among developers, providing a larger talent pool. React, introduced by Facebook, quickly became a preferred option for web app development due to its innovative approach to updating UI elements. Also, JS/TS offers the advantage of sharing libraries between web and React Native applications.

Flutter, influenced by React, offers a similar UI-building approach, and its Dart code is accessible to JS/TS developers, easing the transition between languages. Dart, designed for frontend development, complements UI construction with features like cascade notation, making code more concise in many situations.

JavaScript's lack of type safety can make code less verbose but more error-prone as the codebase grows. TypeScript addresses this by introducing type safety on top of JS syntax, but it still allows having non-typed variables. On the other hand, Dart is fully type-safe and additionally offers sound null safety, enhancing code reliability.

How are things drawn in UI?

React Native and Flutter has chosen different paths of how to draw elements in UI:

  • React Native utilizes native OS elements for rendering. For instance, to display a message box, React Native calculates dimensions, and position, and instructs the OS to show the box with specified parameters. The appearance of the message box varies based on the OS (component style may even be different between the same OS versions).
  • In contrast, Flutter independently renders everything. It has a library of UI widgets mimicking Android (Material) and iOS (Cupertino) elements, closely resembling native OS elements in appearance.

Which approach is better? It is up for opinion, but there are some considerations:

  • OS native components vs custom-drawn components:

o   Some people expect that UI components are updated universally in all apps upon OS version updates (if any style changes) - in such case, React Native would be preferable. However, this introduces a requirement for more testing, as developers must ensure that no UI elements are broken upon OS updates, not to mention that UI components between iOS and Android look different with Android having very many OS flavors with custom styles.

o   In Flutter – drawn UI components will look the same no matter what OS version or even platform you are on – meaning less testing is needed. Additionally – a developer is not limited by the capabilities of native OS components, since everything is drawn by Flutter engine itself.

  • Performance:

o   In React Native, drawing elements involves crossing the JS-native boundary through the React Native Bridge, using JSON serialized messages. This process can lead to slower UI performance if the code isn't optimized. The React Native team is addressing this with the new experimental Fabric engine, employing JSI (JavaScript Interface) for direct communication between JS and native realms, promising significantly improved performance.

o   Flutter doesn't face this issue, as Dart code is compiled to machine code, and drawing occurs in machine code directly using the library Skia (or Impeller in iOS and upcoming Android versions). This setup contributes to smoother and more capable animations in Flutter.

Using platform-specific capabilities

Some operations on a device can only be performed by calling OS-specific functions (such as opening a camera, initiating a fingerprint scan, and recording audio). Flutter and React Native achieve this by using various techniques. Let's observe them:

  • To invoke an OS-specific function, React Native must cross the JS-native boundary and does so by creating a native module (written in Java, Kotlin, Objective-C, Swift, or other platform-specific language), which invokes the desired OS function. Currently (in now called legacy architecture) this is achieved using React Native Bridge, which, as mentioned before, is quite slow because of JSON serialization. But React Native is moving towards new Fabric architecture, which in many cases uses JSI instead of Bridge, making OS-specific calls much faster.
  • Flutter employs a similar approach to React Native modules through Platform channels, facilitating communication between the app's code and OS native code (Kotlin, Swift, etc.) via serialization. Alternatively, Flutter supports communication without serialization, utilizing JNI (Java Native Interface) for Android and FFI (Foreign Function Interface) for iOS or other C language-based OS.

Both frameworks provide many libraries where OS-specific communication is already taken care of and in most cases, there is no need to write platform-specific code. However, in case a need arises, both frameworks provide similar services to achieve so, especially when React Native is used with Fabric architecture.

Supported platforms

React Native supports Android, and iOS, and has additional support from Microsoft for Windows and MacOS. The community has also implemented a support package for the web. It's an excellent choice if you aim for a native look on each OS, making it particularly suitable for web applications where mimicking a mobile app appearance is undesirable.

Flutter, on the other hand, provides out-of-the-box support for Android, iOS, Windows, MacOS, Linux, and the web. Unlike React Native, Flutter maintains a consistent style across platforms, ignoring OS-specific stylistic differences unless developers intentionally customize it. This means Flutter web browser apps may resemble mobile apps, which may or may not align with the desired aesthetic.

Conclusion

We have compared several technical aspects of Flutter and React Native, with a summary:

  • React Native utilizes widely established JS/TS, whereas Flutter relies on Dart, which, although less popular, enforces higher code quality standards.
  • React Native leverages OS to draw native UI components, achieving a native per-OS look, while Flutter draws UI completely by itself, making it look the same on all platforms.
  • Current (legacy) React Native architecture performance suffers because of slow crossing between JS and native realms, but this is being mitigated by new Fabric architecture.
  • Both frameworks provide similar ways to communicate with native functions.
  • Both frameworks have extensive support for platforms, with React Native focusing more on per-OS look, while Flutter’s focus is on a unified look.

 

Martynas Adomaitis SolutionLab

Martynas Adomaitis

Tech Lead