I spent some days with Flutter, a new toolset for building hybrid mobile apps in the Dart programming language. Since I have quite some experience with React Native, I will compare these two frameworks and give my opinion on both of them.
|Environment Setup||Simple due to NPM||Download SDK and manually set PATH|
|Run and Deploy||Simple if Expo - difficult if standalone||Quite simple procedure|
|Adding Modules||Linking may be difficult||Quite simple procedure|
|Debugging||Eventually difficult||Very good experience|
|Testing||Needs integration||Integration exists|
|Hot reloading||Works mostly||Feels a bit better|
|Community||More Popular||Less Popular (as of 04/2019)|
|Documentation||Less detailed||More detailed|
As you see in this table, I made a rough comparison between the two frameworks, to give you an overview of my thoughts. In short: As a pure web developer, it currently makes more sense to rather start with React Native than with Flutter, because of its similarities regarding programming language and styling / layout. Flutter has a great developer experience including debugging and building block integration, for things like navigation or testing.
Getting Started & Documentation
One of the most important things when you get started with a new framework is its setup. Especially for less experienced developers it matters quite a lot, how much time you have to spend setting up a development environment, configuring paths, etc. React Native has an easy and straight forward way of doing this, since is relates on the NPM ecosystem. For Flutter I needed to download the SDK, unzip it and add it to my
Another really important fact is upgrading your project. No matter if the upgrade only fixes minor bugs, patches security issues or includes new features. This process can get really ugly in React Native, since the framework has a lot of independent sub-dependencies or other things. In my experience this always lead problems, for example that your End-To-End test setup would be broken and you had to wait for the maintainers to fix its project. Also, simply the upgrade process itself could get ugly in terms that new config files were needed that you just missed (rn-diff-purge should help with that). Flutter has a really straight-forward upgrade process. You should only need to run
flutter upgrade and that’s it.
To get started with React Native, you can find plenty of example projects (my favourite) , tutorials or courses. This makes it easy to get started building things. As in 2019, the community is way bigger than the one behind Flutter.
As already mentioned before, adding libraries / dependencies to a React Native project can be tricky. Sometimes the linking command
react-native link module can lead to several problems (double linking or only partly). Note that this is not necessarily related to React Native, but rather your project configuration or the module you want to link. So you would need to open the Android and iOS projects to manually link the module. With Flutter, this process feels way simpler. Adding the dependency to your yaml file followed by a
flutter get packages should be enough. This to be said, there is no node package server that you often have to restart our cache-clean, as in React Native.
Hot reloading is a development feature that allows you make changes and see them immediately while to app is running. This means that the app does not have to restart, which can be really nice especially when developing UI features. Both frameworks have this features, but React Native can sometimes make it difficult to configure. Flutter felt a bit better in this regard. If you ever worked with stateful hot reloading, you never want to work without anymore.
Styling and layout of the User Interface is pretty easy in React Native. However, it can still take some effort to make both Android and iOS look pretty. Flutter has a complete different and own approach than React Native. Things like centering a progress spinner can get really interesting in Flutter, in my experience.
State management is the definition of how your app handles data and related flows. In React Native, Redux is a very popular library that does exactly that. It helps you centralize your app’s state and prevents data mutations that may lead to very hard bug hunting. Redux consists of a store with your app’s state, actions, reducers and dispatchers. When you click a button, an action is fired and dispatched by the store. The store decides which reducer dispatches this action. A reducer then simply takes the current state of your app, does something with it (depending on the action) and returns a new state. On this way, the state stays immutable. Since Flutter also supports Redux, state management can be quite similar.
When you do requests to a server, you often have to work with JSON data. In React Native, you can make use of the built-in JSON parse and stringify support. This was a very big disadvantage when I worked with Flutter, since I had to write these transform function by myself.
When it comes to testing, configuration can get ugly in React Native. Sometimes, the test runner’s transformation broke at some point (code could not be transpiled), and you have to know why it happens and how to fix that. This often includes adding or removing babel plugins / presets, which can take some time figuring out. I have not done much testing in Flutter yet, but it seems to work well. You probably don’t need to worry too much about configuring your test suites. Keeping tests simple is always a good thing, and nobody wants to worry about that.
Flutter is different to React Native in terms that in has its own rendering engine. Since there is only a thin layer of C/C++ code, everything else is written in Dart, which gives developers more control and better performance. Flutter might be a better choice than React Native in terms of performance.