Hybrid Power: Flutter Advantages and Benefits
Flutter is a hybrid mobile application development platform from Google that hit 1.0 in late 2018. While it’s a newer entrant in the list of hybrid development frameworks, the great ideas behind it have caused it to quickly catch on among developers.
My goal in this article is to explore these ideas and write about my experiences with Flutter, and why I feel it’s the future of hybrid mobile application development.
Even though there are older hybrid app frameworks in the market, there’s a growing list of big name companies that are choosing Flutter for their mobile applications. While the Flutter showcase page lists a lot of these, here are a few notable apps that use Flutter either for the entire app or for a significant feature:
- The Google Ads app
- GrabFood’s GrabMerchant app
- Alibaba Group’s Xianyu app, which has more than 50 million downloads
- The eBay Motors app
While the Flutter framework is quite capable, it is still relatively new. For the sake of balance, I’ll also discuss some limitations that you should be aware of before committing to Flutter.
My hope is that after reading this article, you have a good idea of the pros and cons of Flutter, and have enough information to decide if you should use Flutter in your next mobile application project.
Flutter Advantages (From a Development Perspective)
As a developer, this is the point of view I am most familiar with and can share the most information about.
Quick Learning Curve
The first pleasant surprise Flutter has for developers is just how quickly it is to get started. It takes less than 30 minutes to finish the installation process and have a working development environment set up. From there, you’re all set to create your first Flutter app.
Popular Editor Integration
Flutter also has great editor integrations. I personally use Android Studio, but there are instructions available to set up IntelliJ, VSCode, or Emacs.
Clean Development Process
Compared to my previous experience with hybrid app frameworks, the development process also feels cleaner. For example, when I used WebViews to display lists with many elements (around 100 or so), I had to deal with high CPU usage, especially when the user was scrolling the list. I resolved those by using Ionic framework elements specifically made for this. In Flutter, there is one accepted way of displaying lists, the
ListView, which has amazing performance out of the box.
Another thing that pleasantly surprised me was the live reload functionality. As a full-stack developer, I was used to frameworks like BrowserWatch providing live reload in the browser.
Native development doesn’t have that (but I think SwiftUI from Apple is making some progress on that front for iOS development). Android and iOS developers typically need to write code and then wait for it to compile and be loaded on the device or simulator before they can see changes.
Flutter provides (a la React Native) a live reload mechanism, where the app code is reloaded on the device as soon as developers hit “save.” This gives immediate feedback, making development a lot faster.
Since the Flutter framework is under active development, there are many places where performance optimizations can be made. This is evident in, for example, Flutter 1.17, which increased rendering performance by up to 50% on newer iOS devices, and decreased memory consumption by up to 70% for certain types of workloads.
Truly consistent UIs across both mobile platforms is another remarkable feature of Flutter. Because Flutter uses its own rendering engine—more on that later—the UI is exactly the same on iOS and Android. Developers no longer have to grapple with platform-specific styling issues to get everything looking exactly like the design: That guarantee is part of the framework.
Language, Tooling, and Extension
Three other smaller, but still important, aspects I feel should be mentioned here are:
- There is a robust plugin manager (pub) included in the default tool chain and a huge library of plugins available through the pub.dev plugin repository.
- Creating plugins to take advantage of native platform capabilities is quite easy, so if developers need access to a platform feature for which no plugin already exists, coding one up isn’t too difficult.
Flutter Advantages (From a Business Perspective)
The biggest Flutter benefit that most businesses think of is only having to hire one team for both the iOS and Android platforms. However, a more important benefit that many businesses overlook is quicker time to market. Leveraging the development advantages in the previous section, a smaller development team can build a beautiful application with native performance that provides the same user experience on both platforms much more quickly using Flutter.
Flutter does allow developers to build some truly beautiful user interfaces. Take a look at a recent challenge from Google and Lenovo to build a beautiful clock face UI for the Lenovo Smart Clock. The winner, Particle Clock by Mickel Andersson, isn’t just uniquely elegant—it also showcases how performant animations are in Flutter.
For businesses considering Flutter but unsure if it’s the right way to go, Flutter can be leveraged incrementally: Preexisting mobile apps can integrate Flutter a single part at a time. In fact, that is how most large companies start out with Flutter, by building a small part of their existing application in Flutter, and then slowly replacing other parts once they see the benefits.
Limitations to Consider Before Using Flutter
In fairness, Flutter, being newer, is not quite as battle-tested as other hybrid mobile application frameworks like React Native—after all, React Native’s end-user reach covers the mobile apps of Facebook, Instagram, Skype, and Discord.
The default answer to “should I use Flutter?” is, for now, a cautious yes. This is because project managers still need to consider which, if any, advanced features they’ll need and make sure those features are available in Flutter before committing to using it. In particular, it’s worth asking which libraries and plugins a team might need to build a particular application. As a newer entry in mobile app frameworks, Flutter doesn’t have the extensive scope of libraries and plugins that React Native does.
For instance, camera support in Flutter isn’t complete yet, with zooming and flash control not yet a part of the official camera plugin. For me, that wasn’t a deal breaker, as I was able to find a third-party plugin when I needed to integrate photo/video functionality in an app I was building.
Another major plugin that you might miss is Google Maps. There are no Dart-native Google Maps plugins, and while there is a plugin to allow integrating Google Maps into your Flutter code, it uses features of Flutter (platform views) that are still in developers’ preview status.
One more thing that won’t affect many projects, but you should be aware of, is that for now, Flutter doesn’t support any 3D capabilities. The team is focusing on 2D only for now. But most applications don’t use any 3D functionality, so this should not be a deal-breaker for the majority of developers.
Some Advice from My Experience with Flutter
Having released three Flutter apps over the past two years, I learned a number of things which I wish I had been told when I was starting out. I’ll list them here in the hopes that they help you in your Flutter development journey.
Flutter is very easy to get started with. I started with a wonderful course on App Brewery. However, after completing the first few modules, I thought that I had learned enough and started building the first app that I launched.
Because of my impatience, I skipped a number of modules in that course which turned out to be important, and I had to learn the lessons of those modules the hard way by making mistakes. Specifically, I would have done a much better job on my first use of Flutter for app development if I had learned a few Flutter best practices:
- How to modularize and structure my Flutter application code.
- How state management works.
- How to authenticate users and track the authentication status across the different pages of my Flutter app.
- How to integrate notifications using the Firebase Messaging package.
I ended up learning all of these things, but had to make a lot of mistakes first. I rewrote significant portions of the first app I built. With my second Flutter app, however, I had learned from my mistakes and ended up doing a better and quicker job.
There are many resources you can easily find by searching Google to learn about the concepts I listed above. You can start out by looking at the links on the Learn More page on the Flutter site.
Another thing I found is that because of how new Flutter is, there is no one pattern for structuring your app. Coming from a mostly Django-based development career, I’m used to knowing that MVC is the pattern to use in my Django apps. iOS also has a clear winner in the MVVM pattern that it follows. Android has its set of guidelines for how to best architect an app.
Flutter has no such architecture pattern that has “won out” over the many possibilities. This was something that gave me a tough time initially. In the end, having developed a number of Flutter apps, I think it’s best to simply choose an architecture and stick with it.
I personally use the
provider package as both a dependency injection and change management framework. My Flutter apps are also roughly divided across three lines:
- Views, which are the widgets that build up the application, including the screens. I inject services and models using the
Consumerwidget from the
Providerpackage into my views so I can build the UI based on the available data. The
Consumerwidget also rebuilds the view when the state changes, which is how my apps react to state changes.
- Models, which are plain old objects that I use to hold structured data.
- Services/controllers, where most of the business logic goes. API interfaces are also coded here, which can retrieve and send data to the API. These API interfaces provide and accept models to pass data around.
The bloc library is also worth considering as an alternative to the
provider package. It has a slightly different architecture, and it uses streams of events and states to connect views and models.
It is a slightly more complex way of managing state than using the
provider library, but it pays off if you have a complex application where you are making changes to the same data from multiple sources and need to respond to those changes from multiple places.
If you end up not using BLoC or
provider, you’ll have to come up with some method of managing state across your application, especially where notifications are concerned.
How Flutter Compares to Other Hybrid Frameworks
React Native is by far the most popular and successful hybrid mobile application framework to date, and with good reason. It took a popular and well-made front-end web framework, React, and allowed millions of front-end developers to start writing mobile applications as well. I’m confident that many of the great mobile apps we have today would never have been made if the developers had to find the time and motivation to learn the native iOS and Android development SDKs.
Against this backdrop, I am confident in saying that Flutter will eventually win out as the leading hybrid mobile application framework. There are a couple of reasons for that.
However, it also means that if developers want to have the same, consistent UI across both mobile platforms, they have to work hard to style the native components to look the same, or use different components altogether that provide the same look and feel across both platforms.
Contrast this to Flutter, where the framework provides its own widgets on all supported platforms. There’s no translation happening, because Flutter doesn’t rely on the native controls to paint the UI. Instead, it uses its own library of controls. The widget library of Flutter does provide widgets that look like native controls, but they’re completely optional.
This approach has its pros and cons. The biggest pro is that you now have the exact same app across both platforms. But you do give up some things to achieve that.
Since Flutter uses its own widgets instead of using the native ones, you can’t use the plethora of existing libraries providing custom controls like you can with minimal work on React Native. In React Native, it’s pretty simple to write a small wrapper around any existing native control and have it work. This is also why right now, there’s no stable Google Maps implementation for Flutter.
However, the ability to embed native controls is being worked on right now and is in developer preview, which means you can use it but might have to contend with bugs. Once it’s released, it will close off this rather large hole in functionality in Flutter compared to React Native.
This same Flutter feature—using its own library of widgets instead of native ones—provides a huge benefit as well when you want to create an entirely new component. In React Native, you would have to build a platform-native component and import it into your application via bindings.
With Flutter, you can build custom components right in your Dart code. You have complete control of the UI with widgets like
CustomPainter that let you draw whatever you need, and you have a library of widgets available that let you implement custom animations. You never need to step outside of the Dart codebase to build these custom widgets.
And this I think is one of the biggest Flutter benefits. You have complete control of your UI from the Dart code and no longer have to worry about learning the native SDK of the platforms you’re developing for.
This is also a downside, though. Because you use web technologies to build your applications, it takes a great deal of care to make sure that the app looks and feels like a mobile app, and not just a website that was scaled down to work on mobile.
While Cordova is a great way to develop an MVP or even the first few versions of your app, the first app I built in Flutter was a port of an Ionic app. The performance improvements we got, especially in views that had a lot of content to scroll through, were noticeable from the first interaction.
I don’t have any experience with Xamarian, so I can’t fairly compare the two. However, during my research, I did come across a great article that does a fair comparison.
While the article ends up with a tie between Flutter and Xamarian, I can confidently say that if I were reading it and had to make a choice between the two frameworks, I would have gone with Flutter because the things that it shines in are the things that I value more.
A Technical Overview of Flutter
Flutter: The “Game Engine” of Hybrid App Frameworks
Among hybrid mobile application frameworks, Flutter has a unique approach. It doesn’t delegate the UI to the native platform, or use a web view. Instead, Flutter uses its own rendering engine to paint the UI. This is similar to how games use a game engine that generates all parts of their UIs, instead of using native controls.
Flutter uses the high-performance, battle-tested Skia graphics engine to draw everything in your mobile application. Using Skia provides two main benefits that I can think of, although I’m sure the Google engineers behind Flutter had a lot more in mind:
- Your app will look exactly the same on all platforms without needing to be customized for each one.
- Your app will get great performance, similar to native applications, because there is no intermediate layer that has to translate your code into native platform code to draw the widgets.
Everything Is a Widget
The Flutter docs talk about Flutter as a “React-style framework.” This is apparent in how apps are built by composing smaller widgets (components in React terminology) together.
However, Flutter takes the everything is a widget approach one step further than any other framework I’ve worked with.
A simple example is padding. With most frameworks, padding is an attribute of the UI elements. In Flutter,
Padding is a widget that can wrap other widgets inside itself and add padding around its child widget.
More uniquely, the
InheritedWidget has no UI and doesn’t provide any user interaction. Its only job is to add information to the widget tree so that at some point deep in the tree, you can pull out that information.
For instance, the root of your application—the
MaterialApp widget—can inject an authentication service into the widget tree using an
InheritedWidget. Now, deep in the tree on some other page, like your user profile page, you can use a method to extract that authentication service and use it.
This everything is a widget approach does take some getting used to. But once you are familiar with it, it becomes a powerful way of building functionality in your applications.
Flutter, Dart, and Digging Into the Source
Flutter is intimately tied in with Dart. While the core rendering engine is built in C/C++, that’s only a small part of Flutter.
The majority of the Flutter codebase is written in Dart, and there are excellent reasons why the Flutter team chose it. But the biggest benefit for me was that I could easily look at the source code of the framework—and all the different widgets it provides—and learn from them.
This is a more powerful advantage than many developers realize. I recommend that most developers try to find answers in the code of their frameworks/libraries, as that not only helps them understand what is happening under the covers but also exposes them to high-quality, well-engineered code, which is a sure way of growing as a developer.
Native Platform Interoperability
While Flutter provides the UI layer, and the business logic is easily handled via pure Dart packages, to access the capabilities of the native platform like geolocation and camera control, using pub.dev’s third-party packages is the easiest strategy.
However, if there is some functionality that you need which isn’t available via an existing package, writing one yourself is not too difficult. I haven’t built any platform-native packages myself, but I have looked at the source code for many out of curiosity.
Even though I’m no native application developer, I was able to mostly understand the native parts of those plugins and see how they connected to the Dart runtime via message passing. For experienced native platform developers, creating a new package to leverage a native capability is going to be very easy.
Should You Use Flutter in Your Next Project?
Hopefully, this article has given you enough information to decide if you can use Flutter in your mobile application project. I have tried to give a balanced picture of Flutter, listing both the pros and cons.
While no one can make the decision for you, I can give you some parting advice on how I might approach the question of using Flutter in my next mobile application. If Flutter’s advantages can provide all the capabilities that an application needs, I would choose it in a heartbeat.
That is because, aside from the few areas where Flutter is currently lacking, all other aspects of it are ones that I have come to admire and rely on in developing and launching the five different Flutter applications in the past year:
- Flutter’s ease of getting started
- The speed gains that can be had from using a framework that was designed from the ground up to focus on speed of development
- The rich ecosystem of readily available Dart libraries and third-party packages
- Flutter’s different but extremely productive way of developing applications using the everything is a widget approach
Those offering mobile app development services would be wise to give Flutter a serious look, if they haven’t already.
I will close by noting one last Flutter advantage: It has some of the best documentation of any library or framework that I have worked with. It’s rare that I google a Flutter question and it’s not answered by a page from Flutter’s own site.