Why I left React Native and moved to Flutter: Part 1

Hello. My name is Dmitry Andriyanov. I've been writing in React Native for two years, now I'm a developer at Surf and I've been writing in Flutter for a year and a half. When I first decided to get serious about Flutter, I would really like to find an article from a developer who switched from React Native to Flutter and get his opinion. Now this developer is me.



Chances are you've seen this kind of feedback about React Native and how companies are moving away from it. I will share my personal opinion from one developer, not a company.



This article is for those who:



  • Not familiar with cross platform and wants to understand the main difference between technologies.
  • He writes in React Native and wants to know what he will benefit from switching to Flutter.
  • Didn't write in React Native, only in Flutter.


Below I will tell you why at one time I chose React Native, I will share the reasons for leaving Flutter and give the main differences between React Native and Flutter, which, in my opinion, are the most important. Much time has passed since leaving React Native - something has changed and fixed. I tried to take this into account, but I might have missed something.







Why I chose React Native



I came to React Native from Web development with React.js in 2017. The company needed a React / React Native developer.



Causes:



  • The same language is JavaScript.
  • The same rules for building a UI and a component system.
  • Cross platform.


Why left for Flutter



React Native is good until you start doing something weighty, with lots of screens and incremental logic, and the application gets harder and harder. I tried various ways to improve performance: shouldComponentUpdate, PureComponent, key usage, memoization, loop optimization, etc., and started thinking about replacing JSCore (Hermes was not there yet). As a result, I came across an advice to try Flutter.



Flutter has richer tooling, better performance, and no React Native issues. Of course, I'm not denying that my RN code might not be the most perfect.



Pros of React Native that got me started with it



1. React Native uses the convenient React.js component framework.



React.js:



function App() {
    return (
        <div className="App">
            <header className="App-header">
                <Image
                    logo={logo}
                />
                <p>
                    Edit <code>src/App.js</code> and save to reload.
                </p>
                <AppLink>
                    Learn React
                </AppLink>
            </header>
        </div>
    );
}
function Image({logo}) {
    return <img src={logo} className="App-logo" alt="logo" />
}
function AppLink({children}) {
    return (
        <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
        >
            {children}
        </a>
    );
}

export default App;






React Native:



function App() {
    return (
        <>
            <StatusBar barStyle="dark-content" />
            <SafeAreaView>
            <ScrollView
                contentInsetAdjustmentBehavior="automatic"
                style={styles.scrollView}
            >
            <Header />
            </ScrollView>
            </SafeAreaView>
        </>
    );
}

function Header() {
    return (
        <View>
            <Text>head</Text>
        </View>
    );
}

const styles = StyleSheet.create({
    scrollView: {
        backgroundColor: Colors.lighter,
    },
});

export default App;






2. No WebView and HTML - native (OEM) platform widgets are used. Communication between JS and the native part happens through a bridge .



About two years ago I wrote applications with a UI part on the WebView side. In the end, the biggest challenge was getting it to be native, especially component responsiveness and scrolling. And using OEM widgets automatically eliminates these problems.



3. CodePush . Allows users to change the application code almost immediately without updating the version from the store.



4. During its existence, a lot of libraries have appeared for React Native.

One of the collections of libraries .



On my first React Native project, I used the react-native-fcm libraryfor push notifications, only notifications were required and nothing else. In another project, we already used react-native-firebase , because in addition to notifications, analytics was needed.



Flutter pros



1. Release.



Stable and reliable version. The simultaneous releases of Dart and Flutter ensure that the new version of Flutter uses the very latest in Dart. Since they are developed by the same company - Google.



2. UI performance.



The UI is rendered on its own Skia engine . Flutter has its own set of Material and Cupertino widgets, which are a copy of the platform's OEM components. This allows them to be used simultaneously on both platforms. For more information on how widgets work, see the Flutter Under the Hood article .



An example of launching an iOS widget on both platforms:







No OEM components and no interaction costs. Although they are an advantage of React Native over technologies that use WebView, they are inferior in flexibility and performance to Flutter widgets. Recently worked on an app using mostly Material widgets for Android and iOS, but platform dependent DatePicker.



Sample UI on both platforms:







3. Hot Reload - Injects updated source code files into a running Dart virtual machine. After that, Flutter rebuilds the widget tree, immediately displaying the changes without restarting the application. This saves a lot of time when designing UI and writing logic.



4. Compilation of Flutter.



In React Native, only JIT compilation. Flutter uses JIT only in development mode - this enables Hot Reload to work. The release build of Flutter uses AOT compilation into native platform files, which is safer and more efficient than React Native, where you can access JavaScript code in release. The release build of Flutter is much faster than the release build of React Native.



Comparison of Native vs Flutter vs React Native performance .



5. Isolates.



In Flutter and React Native 1 process with 1 asynchronous thread and heavy tasks will block the UI.



Way out:



  • Break down into asynchronous operations. They do not block the UI, but run on the same thread.
  • Removing into isolate is an independent process with its own flow, which allows you not to worry about this blockage of the main flow.


The Flutter Dev Podcast has a great release on isolates and libraries for working with them.



6. Everything is a widget.



Thanks to this, widgets can be nested within each other as required by the developers, without special restrictions.



Example: a button containing an AppBar with a title of Switch.



RaisedButton(
  padding: const EdgeInsets.all(10),
  child: AppBar(
    title: Row(
      children: <Widget>[
        Switch(
          value: false,
        ),
        Text('text'),
      ],
    ),
  ),
),






You can write your own widget:



  • A combination of widgets.
  • Using Canvas for more complex geometry.
  • Using a render layer when specific behavior is needed.


I recently wrote functionality that was easiest to do using not a widget layer, but a render layer using RenderObject. But I will talk about this in one of the following articles, where I will describe the problem and its solution.



An article about render layers.



Cons of React Native



1. Still not 1.0.0.



Usually in the project they stayed on a certain RN version. Updates often resulted in library or RN internal device breakage. The automatic version update tools were failing. It was faster to re-create the project on a new version, since outsourcing customers do not pay for the time spent on the update.



They were updated only when the necessary library required it or a critical bug for us was fixed in the new version. In this case, there was a risk that the old libraries might be incompatible with the new version of React Native. But a year and a half has already passed, let's check how with this now. Let's try to update React Native in a couple of minutes, because the customer's time is important to us.



We create a React Native project at v0.61.5 (penultimate at the moment).

react-native init test_version --version 0.61



Run:







Everything is fine.



We initialize the repository, since the upgrade works on top of Git and without it there will be an error:







Run npx react-native upgrade:







A clean project gives an error when upgrading.



Let's follow the link offered in the treminal. List of files to be updated manually:



  • package.json
  • .gitattributes
  • .flowconfig
  • App.js
  • app.js / android / app / build.gradle
  • android / app / src / debug / java / com / rndiffapp / ReactNativeFlipper.java
  • android / app / src / main / AndroidManifest.xml
  • android / app / src / main / java / com / rndiffapp / MainApplication.java
  • android / build.gradle
  • android / gradle.properties
  • android / gradle / wrapper / gradle-wrapper.properties
  • android / gradlew
  • ios / Podfile
  • ios/RnDiffApp.xcodeproj/xcshareddata/xcschemes/RnDiffApp-tvOS.xcscheme
  • ios/RnDiffApp.xcodeproj/xcshareddata/xcschemes/RnDiffApp.xcscheme
  • ios/RnDiffApp/AppDelegate.m


After updating the files, I run upgrade:







Run npm install. Done. The project has been updated.



The main criterion is time. It is spent on updating and fixing problems, or on rebuilding the project from scratch. On Flutter, write "flutter upgrade" in the console and you're done. Flutter will update for all projects at once. There may be breaking changes, but usually there are a couple of them for the whole project and they are very easy to fix.



2. Performance.



It was not enough. Still not as fast as we would like. Testers were constantly bugging low "non-native" performance. Optimizations did not always help. As the application grows, more data is serialized for the bridge and the less responsive.



3. Since native components are used, they look different on Android and iOS.

To achieve consistency, you will have to write an analog of the component for one of the platforms or from scratch for both. Or design a design taking into account these features and differences.



Same UI. IOS on the left, Android on the right.







Additionally



JavaScriptCore



React Native has had old JS Core for Android for a long time. With the advent of Hermes, the situation has improved, but judging by the reviews of familiar developers and tests, everything is not so simple.



Comparison of JS engines .



Expo



It is difficult to attribute it to the pros and cons. It provides important libraries and functionality out of the box, but it has its own problems that neutralize its pros. If you need some platform-level functionality that is missing in Expo or an external library that uses native code, then you have to push the project and the pros of Expo either disappear or turn into its cons. React Native init vs Expo .



Cons of Flutter



It would be unfair not to mention them. Still, this is not a silver bullet.



1. Fewer specialists and vacancies.

Fewer developers and companies building on Flutter compared to React Native. When I was looking for a job on Flutter in May 2019, I came across only 3 companies.



2. The number of libraries is less than in React Native.

Due to the fact that Flutter is a younger technology, there are much fewer libraries for it, but their number is actively growing. But for more than a year of work, this did not give me any special problems, since all the necessary libraries are available.



3. Not suitable for:

  • Games.
  • Applications tied to work with iron.
  • Augmented reality applications. Since you need to implement the logic separately for each platform.




But if there is a lot of common UI, perhaps the option of using platform channels to interact with native code or integrating Flutter into a native application will do.



Documentation



React Native has pretty good documentation that answers many questions that arise. It is gradually improving (before you could stumble upon blank pages: there is a title, but no content) and the material is getting better.

In Flutter, the documentation is awesome. Examples, explanations, recipes with examples, videos. If there is a problem using something, the documentation is able to solve it.



Entry threshold



In both cases, the entry threshold is quite low.



  • React Native - you need to know JS, React and you can start.

  • Flutter — JS / Java / Kotlin / Swift / C ( JS — ), Dart .

    React Native, Flutter .






React Native



  • .
  • .
  • .
  • .
  • .


Flutter



  • , . .
  • , .
  • .
  • .
  • .


The user doesn't care what you use for network requests Http or Dio.

Have you been looking for JS developer of the day or Flutter developer of the month. The main thing is that the application performs the required tasks and is productive. Flutter allows you to meet these requirements much more efficiently.



The analysis of solving the same problems using Flutter and React Native will be in the second part of the article.



All Articles