This article assumes no prior knowledge of Flutter or Dart.
In this series, we’ll take a look at a new mobile app development framework called Flutter.
In the past few years, many tools were developed to help developers create cross-platform apps. This was brought about by the need to release mobile apps that can run on both Android and iOS platforms a lot more quicker. Having two or more teams working on each platform is expensive, and most startups can’t really afford it. That’s why tools like Cordova, Ionic, React Native, Xamarin, NativeScript, Fuse, and many others were developed.
In this part, you’ll learn what it is, how it works, some of its pros and cons, and how it compares to React Native.
In the second part, you’ll learn how to create an app with Flutter.
This tutorial assumes no previous knowledge of Flutter.
What is Flutter?
Flutter is a new mobile app development SDK from Google. It allows you to develop apps which run on both iOS and Android. Flutter has built-in Material Design and Cupertino widgets which you can use to create beautiful and professional looking apps.
Flutter uses the Dart language for both its SDK and the code written by the developer.
Flutter is a complete framework. This means that everything that you need to build and test a mobile application is included out of the box:
- UI rendering
- Widget library
- State management
- Hardware APIs
How does Flutter work?
Flutter is built with C, C++, Dart, and Skia, a 2D rendering engine.
Each Flutter app is composed of the Flutter SDK and the Dart code written by the developer. Flutter uses ahead of time (AoT) compiling to compile both the Flutter SDK and the Dart code into a native ARM library. This is then executed by a “runner” that handles all the rendering, input and event handling inside the app.
The diagram below is a high-level representation of the Flutter system architecture. At the very top are the themes for both the Android (Material Design) and iOS (Cupertino) platforms. As the developer, you wrap Flutter’s basic widgets with these themes depending on which platform you’re working with.
Note that these widgets are Flutter’s own widgets, they don’t actually use the platform’s OEM widgets like React Native or NativeScript does. This brings us to the “Rendering” part in the diagram below. Flutter uses Skia to draw these widgets into the screen. If you’re familiar with Unity, Flutter works in a similar way. The underlying framework takes care of the animation, painting, and gestures as the user interacts with the widgets that were rendered. Behind the scenes, Skia takes care of updating what the user sees on the screen. The Flutter SDK and the Dart code written by the developer is executed via the Dart VM.
That was only a quick overview of how Flutter works. If you’re interested in diving deeper, be sure to check out these technical documents:
Pros and cons of Flutter
In this section, we’ll take a quick look at some of Flutter’s advantages and disadvantages. These are in terms of developer productivity, widget support, and app performance. Note that these are true at the time of writing this tutorial. Flutter is in constant development, so what’s missing today might already be supported tomorrow.
- Flutter is open-source. On top of the dedicated Google team that works on Flutter, everyone is also welcome to contribute to the development of Flutter and publish their own packages.
- Flutter has great documentation. Everything you need to know about the Flutter APIs and internals is well-documented.
- Allows your existing Java, Swift, and Objective-C code to be reused to work with native functionality on iOS and Android.
- Flutter uses its own widgets, not the one which comes with Android and iOS (OEM widgets). This means we don’t have to deal with implementation details for both platforms.
- Performance is very close to native performance. Unlike React Native which needs to go through a “bridge” to interact with native components, Flutter has a “runner” which renders the widgets and handles interactions.
- Flutter comes with nice developer tooling out of the box.
- Flutter’s interop and plugin system are designed to allow developers to access new mobile OS features and capabilities immediately when Apple or Google releases them.
- Fewer widgets are available for iOS. Flutter’s Cupertino widget library lacks some of the essentials like the datepicker, stepper, and progress indicator.
- Doesn’t have much support when it comes to text-editors and IDE’s. Currently, it’s only compatible with IntelliJ IDEA, Visual Studio Code, and Android Studio.
- Unlike in React Native, styling is a bit messier in Flutter. Each widget has their own styling which you put right in the rendering code. Each widget can have children so things can get really messy because the structure and styling are mixed together.
- You can’t transfer your existing CSS knowledge to style your widgets. Though a few concepts still apply (for example, margins and paddings), CSS properties and values are not applicable to Flutter.
- Not a lot of third-party library support. If you need to use services like Auth0, Pusher, Twilio, or Realm, you will most likely have to create your own custom integration.
- No built-in support for common functionality such as maps and camera. Though you might find someone who’s currently working on it on the Dart packages website.
- Flutter hasn’t been tested on tablets so there might be some UI issues on tablets. At the time of writing this article, tablet support isn’t really a priority so be sure to check out this issue to keep track of tablet support if you plan on developing for tablets.
How does Flutter compare to React Native?
The most popular cross-platform app development framework today is React Native, so developers trying to check out Flutter will naturally come to ask this question: “How does Flutter compare to React Native?”.
If you do a quick Google search, you will come across articles which compare the two, and probably with some other framework like Ionic, NativeScript, and Xamarin. There are probably others, but the main question you’re really asking is: “is Flutter a viable solution for cross-platform app development?”. And that’s why I chose React Native as the framework to compare with Flutter. Because it’s already been battle-tested, lots of well-known companies are using it and it has a huge community behind it.
We will be using the following criteria for comparing the two:
- Developer Productivity
- User Experience
- Hardware API Support
The criteria above are arranged according to its level of importance. Developer Productivity and User Experience are more important while Hardware API Support is less important. Note that this prioritization is hugely based on my own personal experience as well as the research that went into writing this article.
We already know that both React Native and Flutter allow us to write code once and it will run everywhere. If you have worked with React Native in a fair amount of time, you already know that this isn’t completely true. You still have to deal with configuration files (
build.gradle) on both platforms, you still have to deal with the different UI implementations, and work with either Java, Objective-C, or Swift code whenever you need to work with native functionality.
In Flutter, things are a bit different. You still have the
ios folders in your project but most of the time you won’t really need to touch the files in there.
How fast the hot reload is is another important factor. Nothing kills productivity more than having to wait a minute for one simple change to show up in the live preview. Both React Native and Flutter have a hot reload feature, but the one in Flutter is faster.
Other than that, there are other areas which developer productivity depends on:
- Learning curve
The first thing that developers will look at when learning a new technology is the documentation, so it plays a big role in developer productivity. Even advanced users will need to use it from time to time when they’re working with a new API.
If you give yourself a few minutes to scan through the documentation of React Native and Flutter, you will quickly see the effort that went into creating the documentation. The documentation is not just about describing the different APIs, functionalities, components and other features that are available in the framework. It’s also about making it easy for both newcomers and advanced users to find what they need to know about.
React Native’s documentation is very shallow, it teaches you one thing and then moves on to the next. It doesn’t allow you to easily dig deeper into one specific concept. If you’re a React Native developer, you might have noticed that there are lots of poorly documented (or not documented at all) APIs. So you have to look for it somewhere else, or just go on with your life not knowing that such capability (or bug) exists.
Flutter’s documentation is very easy to use, all the important concepts and features that you need to know are visible in their sidebar. If you want to dig deeper, they also have API documentation. For example, all the classes that are available for constructing widgets with the material library are well-documented. It includes information about what the constructor expects, which properties you can pass in. Best of all, their search has auto-suggest, this is very helpful if you’re not exactly sure what you’re looking for.
They even take one step further with their Codelabs section, where it teaches the beginners how to create their very first Flutter app.
They also introduced the idea that everything is a widget, and that includes adding styles to other widgets:
padding: new EdgeInsets.all(8.0),
child: const Card(child: const Text('Hello World!')),
In the code above, we’re adding an 8px padding all around a card widget. Just by looking at this code, you’ll see that you can’t really transfer your existing CSS knowledge in styling Flutter apps, although basic concepts like margin and padding still apply.
In the beginning, most of your time will be spent on familiarizing yourself with how to build widgets, learning the Dart syntax for the different Flutter APIs, and the tooling around the Flutter framework.
Overall, Flutter’s learning curve is only steep in the beginning, but it should reach a plateau once you get the basic concepts down.
Without further explanation, we already know who the winner is, it’s React Native. This is mainly because of two facts:
- React Native entered the scene first. It was initially released in 2015 while Flutter is only released in 2017.
Even though this is the case, let’s take a moment to examine how well Flutter is doing compared to React Native when it comes community and overall public interest:
With the numbers above, you can really see the difference between Flutter’s community and React Native. That said, those numbers shouldn’t be underestimated as it’s expected to grow as more and more people realizes the potential of Flutter.
If we go over at Google Trends, we can see that the overall public interest with React Native and Flutter is climbing up at a steady pace in the past 12 months. Flutter peaked at around the first quarter of 2018. This suggests that companies and independent developers worldwide are checking out Flutter as an alternative for their mobile app development needs:
The availability of tools that makes the work of a developer easier and more pleasing plays a huge role in their productivity as well. Tooling includes:
- Text-editor and IDE support - code completion, debugger, simulator integration.
- Command-line tools - for checking system requirements, creating a new project, hot reload.
- Libraries and UI kits - for implementing different kinds of functionality like payment processing and social login.
- Third-party services - continuous integration, error reporting.
This is another area where the huge community support in React Native really trumps Flutter.
React Native is supported in popular text-editors like Atom, Sublime Text, WebStorm, Visual Studio Code. While Flutter is only supported in IntelliJ IDEA, Visual Studio Code, and Android Studio.
For command-line tools, while Flutter only has its built-in CLI, it comes packed with a lot of features. Some of the most useful ones include
doctor which checks if your machine has all the necessary software to build apps with Flutter,
create for generating a new Flutter app,
install for installing Flutter packages and
build for building the app:
This is a far cry from what the React Native CLI offers as it only allows you to generate a new project, link native modules, and run the development server. But even though this is the case, the community compensates by creating tools like the Ignite CLI and Haul.
On the other hand, Flutter taps into the Dart package repository for its third-party library needs. Unlike React Native, these packages will often need to be written from scratch to utilize the Dart syntax as well as work with the APIs exposed by the Flutter SDK.
Overall, the winner in the developer productivity criteria is React Native. The only sub-criteria where Flutter won is the documentation, while React Native took all the rest.
Winner: React Native
When it comes to User Experience, Flutter has the clear advantage because it’s drawing the UI directly on the native platform’s canvas. As explained earlier in the section on how Flutter works, this is theoretically faster than how React Native works, which is to communicate with the native platform via a “bridge”.
I can’t really present you with hard numbers, but someone has already done the benchmarking before. If you want to know the details, be sure to check out this tutorial: Examining performance differences between Native, Flutter, and React Native mobile development. The results in that tutorial say that React Native uses more CPU while Flutter uses more memory. The difference is only small for both instances, but the app used as an example is a simple one (a stopwatch app). What we don’t know is whether the usage continue to rise at the same rate as the app demands more memory and CPU from the device.
Using those results, I’m not going to give credit to either. CPU and memory usage should be both efficient. But then again, it all depends on the app that you’re building. If your app requires a certain CPU intensive task to finish at the least amount of time then CPU efficiency is the least of your concern, because you need all that juice to complete the task faster. On the other hand, if you expect your users to be running your app along with others, then you should prioritize CPU efficiency instead.
Hardware API support
When it comes to hardware capability support, both React Native and Flutter come with a decent set of hardware APIs out of the box.
Even though React Native doesn’t have support for camera, Bluetooth, and biometrics, developers who need them usually create a native module and upload them on GitHub.
In Flutter, most hardware APIs that are needed for most apps are already included in their built-in collection of APIs. If you need something that isn’t already supported, you can search for it on the Dart packages website. Most likely, someone has already started developing a package for it. But just like in React Native, some packages only support one platform.
Yet again, React Native wins this round because of the sheer number of hardware capabilities being exposed by other developers. Even though some of those have bugs or have poor support, it’s still better than implementing something from scratch.
Winner: React Native
If you want to learn more about Flutter, here a few tutorials that can help you understand it further:
That’s it! In this tutorial, we’ve taken a quick look at Flutter, a promising new mobile app development from Google. You learned some of its pros and cons, and how it compares to React Native.
At the end, which framework you choose all depends on whether you can afford to invest more time and resources in learning Flutter or not. Flutter definitely has a lot of potential, and it deserves to be checked out by native and cross-platform developers alike.
Stay tuned for the second part of this tutorial series where we’ll take a look at the basics of creating an app with Flutter!