On the official Flutter Website, Flutter is defined as the Google’s UI toolkit for building beautiful, natively compiled applications for mobile (Android, iOS ) desktop (Linux, Mac, Windows, Google Fuchsia) and the web from a single codebase. The first version of Flutter was known as codename “Sky”, ran only on Android operating system, was introduced in 2015 at the Dart Developer Summit On December 4, 2018, Flutter 1.0 was released at the Flutter Live event, denoting the first “stable” version of the Framework. You can watch the Flutter Live announcements and updates (livestream) here.
Since then Flutter has improved a lot in terms of performance. Recently, on December 11, 2019, Flutter Interact took place and it brought a number of improvements to the framework with the introduction of Flutter 1.12. A summary of all the announcements in Flutter Interact is available here.
What is Flutter - The gist of it
Flutter has been around already since 2015 when Google first introduced it, but the buzz around it has grown stronger only lately. It’s a cross-platform tool intended for creating Android and iOS apps from a single code base by using a modern, reactive framework. Flutter apps are built using Dart, a simple object-oriented programming language. The central idea of Flutter revolves around widgets. The entire UI is made of combining different widgets, each of which defines a structural element (like a button or menu), a stylistic element (like a font or color scheme), an aspect of layout (like padding), and so on. Flutter does not use OEM widgets, but provides its own ready-made widgets which look native either to Android (Material Design) or iOS apps (Cupertino). It’s also possible to create custom widgets. Look here for a technical overview.
In terms of popularity, Flutter is making good progress. While Flutter had made it to the top 100 software repos based on GitHub stars by the time release preview 1 was announced in June 2018, it has risen in the ranks and is now among the top 30. Two years later Flutter SDK ranks as top 10 software repo on Github, following giants like Linux, vue and vscode. This, without a doubt, is a promising trend. Thousands of Flutter apps have made its way to app stores, among these the Alibaba app with 50 million users.
Read more about what the Flutter team has to say about their first stable release and what’s on their product roadmap for 2020.
You can find some of the apps created using Flutter on their official Showcase webpage.
Benefits of Flutter
Without making any comparisons with other platforms, here’s a list of some of the features and qualities that may make you consider having a go at Flutter:
- High productivity. Since Flutter is cross-platform, you can use the same code base for your iOS and Android app. This can definitely save you both time and resources.
- Great performance. Dart compiles into native code and there is no need to access OEM widgets as Flutter has its own. This means less mediated communication between the app and the platform. As Wm Leler puts it: “Flutter is the only mobile SDK that provides reactive views without requiring a JavaScript bridge.” All of this contributes to fast app startup times and less performance issues.
- Fast and simple development. One of the most lauded features of Flutter is hot reload which allows you to instantly view the changes made in the code on emulators, simulators and hardware. In less than a second, the changed code is reloaded while the app is running with no need for a restart. This is great not just for building UIs or adding features but also for bug fixing. As far as simplicity is concerned, Flutter claims in its docs that programming with Flutter is so easy that no prior programming knowledge is required: “Experience with object-oriented languages is definitely helpful, but even non-programmers have made Flutter apps!” There’s only one way to find out whether this is true.
- Compatibility. Since widgets are part of the app and not the platform, you’ll likely experience less or no compatibility issues on different OS versions. This in turn means less time spent on testing.
- Open-source. Both Flutter and Dart are open-source and free to use, and provide extensive documentation and community support to help out with any issues you may encounter.
Flutter vs React Native vs Xamarin
There are cross-platform frameworks like Xamarin, React Native already available in the market to develop iOS and Android apps with single code base. While Flutter is more like React Native and Xamarin in terms of concepts there are huge differences in the technical architecture of all these frameworks. Let’s explore, how Flutter compares to existing cross-platform frameworks with following criteria.
- Programming language
- Technical architecture
- Installation
- Setup and project configuration
- UI components and development API
- Developer productivity
- Community support
- Testing support
- Build & release automation support
Programming language: JavaScript vs Dart vs C# (.NET)
The key benefit of using a cross-platform mobile app development technology is the ability to use a single programming language to develop apps for both iOS and Android.
React Native — JavaScript
React Native uses JavaScript to build cross-platform apps. JavaScript is a very popular language in the web community at the moment. It is commonly used with React and other popular JavaScript frameworks. Thanks to React Native, web developers can build mobile apps with a little bit of training. With this in mind, companies adopted React Native as a no-brainer. JavaScript is a dynamically typed language and anything can be done with JavaScript, which is good and bad at the same time.
>> Check the detailed comparison of Dart vs JavaScript
Flutter — Dart
Flutter uses Dart programming language which was introduced by Google in 2011 and is rarely used by developers. Dart syntax is easy to understand for JavaScript or Java developers as it supports most of the object-oriented concepts. It’s easy to get started with Dart as there is great and easy-to-follow documentation available on the official Dart site here.
Xamarin — C# (.NET)
Xamarin has been using the C# language from day one to build cross-platform apps. C# is a very popular language as it’s been widely used in the Microsoft community since ages. C# has been used to build .NET frameworks since 2002 and got popular with its cool features like portability, metaprogramming and functional programming.
As JavaScript is widely used by most web developers, it’s easy to adopt the React Native framework. On the other hand C# is also very popular language as it’s been around for a long time and is backed by Microsoft. Dart also has a great feature set, but it’s rarely used and less known in the developer community.
Technical architecture
When choosing a cross-platform mobile app development framework, it’s essential to consider its technical architecture. By knowing the internals of the framework, we can make an informed decision and choose the one that is better for our project.
React Native — Flux
React Native architecture heavily relies on JS runtime environment architecture, also known as JavaScript bridge. The JavaScript code is compiled into native code at runtime. React Native uses the Flux architecture from Facebook. There is a detailed article on the core architecture of React Native here. In short, React Native uses the JavaScript bridge to communicate with the native modules.
Flutter — Skia
Flutter uses the Dart framework which has most of the components inbuilt so it’s bigger in size and often does not require the bridge to communicate with the native modules. Dart has so many frameworks, like Material Design and Cupertino, packed inside which provide all the required technologies needed to develop mobile apps. The Dart framework uses Skia C++ engine which has all the protocols, compositions and channels. The architecture of the Flutter engine is explained in detail in Github Wiki here. In short, Flutter has everything needed for app development in the Flutter engine itself.
Xamarin — Mono
Xamarin uses the Mono execution environment for both iOS and Android platform. In the case of iOS, Mono execution environment runs along with Objective-C runtime and on Unix kernel, while in the case of Android, it runs along with Android Runtime on Linux or other kernel. Microsoft documentation provides a detailed explanation of iOS and Android architecture used with Xamarin. Xamarin also has Swift runtime support, but this lives in a separate repository here and doesn’t seem to be official.
Flutter engine has most of the native components in the framework itself and it doesn’t always need a bridge to communicate with the native components. Xamarin’s Mono execution component also reacts with Java or Objective-C runtime directly and uses most of the native code there.
Although Xamarin architecture looks solid, it doesn’t have great support for the Kotlin or the Swift runtime which are official runtimes for developing Android and iOS apps. React Native, however, uses the JavaScript bridge to communicate with native modules, which results in poor performance.
Installing Flutter vs React Native vs Xamarin
The installation method should be straightforward without having too many complicated steps so that it could be easily learned by developers that are just starting with it.
React Native — NPM
The React Native framework can be installed using the Node Package Manager (NPM). For developers that have a JavaScript background, installation of React Native is easy, whereas other developers would need to learn the node package manager. The node package manager can install the packages locally or globally. The developers will need to understand where exactly the binary is located. Whilst installing React Native on macOS, we need to have the HomeBrew package manager as well. In short, we need to run the following commands to install React Native on macOS:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install node
brew install watchman
npm install -g react-native-cli
After running these commands, we can access react-native from the command line.
Flutter — Binary download from source
Flutter can be installed by downloading the binary for a specific platform from Github. In the case of macOS, we have to download the flutter.zip file and add it as a PATH variable. We can do this from the command line:
curl -O https://storage.googleapis.com/flutter_infra/releases/beta/macos/flutter_macos_v0.7.3-beta.zip
unzip flutter_macos_v0.7.3-beta.zip
export PATH=[PATH_TO_FLUTTER__DIRECTORY]/flutter/bin:$PATH
Flutter should improve the installation method by supporting package managers like Homebrew, MacPorts, YUM, APT, etc so that users wouldn’t need to perform these extra steps during installation.
Xamarin — Visual Studio (Xamarin SDK)
Xamarin is usually used with the Visual Studio IDE, Xamarin SDK for iOS and macOS can be installed into Visual Studio afterwords. The step-by-step installation guide for installing Visual Studio with Xamarin SDK can be found here. There is hardly any documentation or resources about installing or using Xamarin without Visual Studio.
Xamarin installation is totally dependent on the Visual Studio IDE, while Flutter installation can be done via command line. Flutter installation seems to require extra steps for adding the binary to PATH and downloading it from the source code. However, installing Flutter is much more easier and lightweight and Flutter can be installed without any dependency on IDE.
Both Flutter and React Native lack one-liner installation with native package managers for a specific OS, but Flutter installation seems to require extra steps for adding the binary to PATH and downloading it from the source code, which might be useful for the non-JavaScript developers. React Native can be installed by just using package managers and without the hassle of downloading the binary from the source.
Setup and project configuration
The process of setting up the developer machine to use the new framework takes time. It requires lots of configuration of software installations. The technology should have proper documentation to get users up and running.
React Native
The getting started guide of the React Native project assumes that the developer already has all the required setup for developing for iOS and Android. There is little info on the Xcode command line tools but it won’t be enough to get going. The documentation directly jumps to the step of creating a new project. A new React Native project can be created and run on iOS simulator using the following commands:
react-native init MyProject
cd MyProject
react-native run-ios
There is no setup guide for Android projects in the React Native document.
Flutter
The getting started guide for Flutter has detailed information on IDE setup and platform setup for both iOS and Android. You can read all the required setup details on Flutter install for macOS here. On top of this, Flutter has a CLI tool called flutter doctor which can guide developers through the setup. It inspects which tools are installed on the local machine and which tools need to be configured. Once the flutter doctor command is happy, we can carry on with creating a new Flutter app. There is a separate page on how to configure the editors to get going with Flutter. Once all the setup is done, we can create and run a new Flutter app from CLI:
flutter create MyProject
cd MyProject
flutter run
At this stage, you should have all the setup and configuration for the Flutter project.
Xamarin
As Xamarin configuration is heavily dependent on Visual Studio and the Xamarin SDK, the developers who are already familiar with the VS Code can get up and running very quickly. However, Xamarin requires separate configurations for iOS and Android, i.e Xamarin.iOS & Xamarin.Android. The Xamarin getting started guide for iOS and Android explains the onboarding process for new developers, but Xamarin is heavily dependent on Visual Studio. If the developer isn’t from the Microsoft ecosystem, it would mean a longer learning curve to get acquainted with Visual Studio and learning the Xamarin SDK. Xamarin has Xamarin University with loads of guides for smooth onboarding of new developers.
The Flutter getting started guide is much simpler than Xamarin’s as softwares required for onboarding are lightweight and easy to install. Also softwares are not dependent of any proprietary softwares. Compared to React Native, it’s clear that Flutter offers better documentation and CLI support for setup and configuration.
UI component and development API
When developing cross-platform mobile apps, support for the native component is key. Without the support of the native component, our app won’t feel like a native app. It’s very important that the framework has an API to access the native modules without any pain.
React Native — Less components
The core React Native framework provides just UI rendering and device access APIs. In order to access most of the native modules, React Native has to rely on third-party libraries. React Native is too much dependent on third-party libraries. The full list of development components and the official APIs can be found here.
Flutter — Rich in components
Flutter framework is bundled with UI rendering components, device API access, navigation, testing, stateful management and loads of libraries. This rich set of components removes the need to use third-party libraries. If you get the Flutter framework, it means you will have everything needed for developing mobile apps. Flutter also has widgets for Material Design and Cupertino that allow developers to easily render the UI on both iOS and Android platform.
Xamarin — mature component
Being the oldest cross-platform SDK, Xamarin has solid documentation of its development API. Xamarin supports multiple platforms, like iOS, Android, Forms, macOS, watchOS, tvOS, etc, which in turn have lots of UI components and modules in place for developers to build on. Xamarin also has documentation for developing individual components, like layout, buttons, pop ups, databases, etc.
Flutter is rich in development APIs and UI components while React Native is too much dependent on third-party libraries. On the other hand with its rich set of documentation and a development API, Xamarin has put itself in a strong position over Flutter. Flutter still has a long way to go to allow developing complex UIs, animations and games. On the other hand, Xamarin also supports more platforms than Flutter
Developer productivity
Developer productivity is the key to building apps faster. In this regard, it’s very important to be able to focus on app development without any kind of wait or distraction.
React Native
If the developer is skilled in JavaScript, then it’s fairly easy to use those skills for cross-platform app development. React Native has a hot reload feature which saves a lot of developer time while testing the changes in the UI. In terms of IDE support, developers are free to use any text editor or IDE of their choice.
Flutter
Flutter also has a hot reload feature and it’s very easy to get started with the demo app. However, as the complexity of apps grows, developers would need to learn and adopt the new Flutter concepts. In addition, Dart is not a common programming language and there is a lack of support for it in many IDEs and text editors.
Xamarin
Xamarin has loads of modules and a great development API; however, it heavily depends on the Visual Studio IDE. Developers from the non-Microsoft stack will struggle to learn all the concepts of VS Code or a similar IDE. Also, learning C# will be require a long learning curve. And when compared to editors, IDEs are heavy-weight and building and compiling things takes time. Xamarin uses AOT compilation for iOS for the build and JIT/AOT for Android, so getting the UI changes in the devices might take some time. Xamarin renders UI in terms of the nativeUIControllers. There are a lot of resources online for Xamarin developers to solve the common issues.
Being a mature frameworks, both React Native and Xamarin have great developer support in terms of IDEs and language features. Flutter is fairly new at this point but will catch up very soon as the community around Flutter grows.
Community support
As soon as developers start to show interest in a technology and adopt it in their development process, they form a community to share knowledge. A strong community helps developers to learn from each other and solve the problems they are facing.
React Native
React Native launched in 2015 and has gained in popularity ever since. There is a community of React Native developers on GitHub and lots of meetups and conferences around the world. One of the most recent conferences on React Native was React Native EU held in Poland, but there are meetups taking place in almost every major city in the world.
Flutter
Flutter has been around for a while but it gained a lot of attention when Google promoted it in the Google I/O conference in 2017. The Flutter community is growing rapidly these days, meetups and conferences are taking place online. The biggest so far was Flutter Live in 2018, where Google announced the release of Flutter 1.0. In short, the Flutter community is growing rapidly; yet, there are still not enough resources for developers to solve common issues.
Xamarin
Xamarin has a huge community spread all over the world. There are community forums to discuss problems, issues and proposals. Also, Xamarin has a Twitter handle for all the Xamarin related events. There are some conferences as well for Xamarin-related talks, like Xamarin Developer Summit. Being the oldest cross-platform mobile app development framework, the Xamarin community has more involvement from developers.
The React Native community and resources have grown in size since the framework was launched. The Xamarin community is way bigger than that of Flutter, especially as Xamarin has become so popular in the last few years. The community grows even faster now that Xamarin has been acquired by Microsoft. Flutter is still fairly new although community support is growing rapidly.
Testing support
Writing tests is a great way to get quick feedback on the code. There is always a testing framework associated with every mature technology to allow developers to create unit, integration and UI tests for the apps.
React Native
React Native is a JavaScript framework and there are a few unit level testing frameworks available in JavaScript. The tools like Jest can be used for snapshot testing. However, when it comes to integration or UI level testing, there is no official support from React Native. There are third-party tools like Appium and Detox that can be used for testing React Native apps but they are not officially supported.
Flutter
Flutter provides a rich set of testing features to test apps at unit, widget and integration level. Flutter has great documentation on testing Flutter apps here, you can also read the Codemagic blog on testing Flutter apps for detailed information on how Flutter apps can be tested. Flutter has a cool widget testing feature where we can create widget tests to test the UI and run them at the speed of unit tests.
Xamarin
Xamarin supports all kinds of testing within Visual Studio, e.g unit tests and UI tests. Xamarin also has its own cloud test environment for running the tests. Xamarin unit testing can be set up for each individual platform project as mentioned in the docs here. On top of unit testing, Xamarin has dedicated support for UI testing, Xamarin.UITest API. However, Xamarin apps can be tested with other third-party testing frameworks like Appium independently or with native test frameworks like XCUITest or Espresso. You can read more about the testing Xamarin apps in Visual Studio here
The React Native community has no official support for integration and UI level testing, while both Xamarin and Flutter have rich set of testing features.
Build & release automation support
Releasing mobile apps to the App Store or Play Store is a painful process. It involves the complex task of code signing all another application setup. When it comes to cross-platform mobile app development, it gets even trickier.
React Native
The React Native official documentation doesn’t have any automated steps to deploy the iOS apps to App Store. However, it provides a manual process for deploying the app from Xcode. There is an article on how to deploy React Native apps to App Store here but the entire process looks manual. However, we can use third-party tools like fastlane to deploy iOS and Android apps written with React Native. The process of using fastlane to ship React Native apps is described in this article. This means that React Native has to rely on third-party libraries for build and release automation.
Flutter
Flutter has a strong command line interface. We can create a binary of the app by using the command line tools and following the instructions in Flutter documentation for building and releasing Android and iOS apps. On top of this, Flutter has officially documented the deployment process with fastlane here.
Flutter has a great build automation tooling and can be used to deploy apps from the command line. React Native apps lack support for the CLI tools that are officially supported for build automation.
Why iOS developers should pay attention to Flutter?
Flutter vs iOS
In the initial days of iOS development, the programming language used by Apple was Objective-C which most of the developers hated at that time but were forced to use as it was the only option available if you wanted to carry on with iOS development at that time. But fast-forward to 2014, Swift was introduced which was type-safe and used concise but expressive syntax, and developers just loved it. It was also fully compatible with Objective-C and the existing iOS APIs. Though the APIs that were used by Swift were not that good initially, they are a lot improved now.
Flutter was initially released keeping in mind these four pillars: Beautiful, Fast, Productive & Open. And after one year it has proven to hold onto it.
Most of the cross-platform app developments frameworks that are present, suffers from bad performance and stability issues. They are easily identifiable when they are run beside a native app. Flutter has bridged this performance gap to a large extent in comparison to other cross-platform frameworks, like React Native and Xamarin.
How did Flutter became as performant as a native app? The answer lies in its architecture and also the language used by Flutter, i.e., Dart.
As an iOS developer if you want to try out Flutter then there is a nice Official documentation available.
Read Why should Android developers pay attention to Flutter.
Architecture
Native Apps
In the native apps, whether it is Android or iOS, the native app code talks to the Platform to create OEM Widgets or for accessing various Services like audio, sensors, camera, etc. The widgets are rendered to a screen canvas, and events are passed back to the widgets. This architecture restricts the widgets to be reused across all platforms as they are OEM specific. And, this is the reason we have to write whole app for each platform separately.
Before moving on to Flutter, let’s checkout the architecture of another popular cross-platform solution, React Native.
React Native Apps
React Native apps are written in JavaScript, so to access the OEM widgets it has to use a bridge to talk to the Platform. This is where the bottleneck of this Framework lies.
So, the solution from React Native developers:
In order to architect performant React Native apps, we must keep passes over the bridge to a minimum.
Flutter Apps
Now, coming to the Flutter apps. Flutter solves the most challenging part of the other cross-platform frameworks, i.e. getting rid of the BRIDGE. Flutter does not use the OEM widgets, it provides its own widgets. Flutter moves the widgets and the renderer from the Platform into the app, which allows them to be customizable and extensible. This also helps Flutter to maintain the consistent 60 FPS.
Dart
Another reason that developers love Flutter is because of the Dart Language.
Dart is an object-oriented, class defined, garbage-collected language using a C-style syntax that trans-compiles optionally into JavaScript.
Though Swift is also a very good and modern language, but Dart has some features that separate it from the other languages:
-
Dart uses AOT (Ahead Of Time) compilation, which gives the fast startup and fully customizable Flutter widgets.
-
Dart also uses JIT (Just In Time) compilation, which is the main reason that Hot Reload exists. I will talk about it in a bit.
-
Dart has a garbage collector built in the language. This enables Flutter to achieve smooth animations and transitions that run at 60fps.
-
Dart allows Flutter to avoid the need of a separate declarative layout language or visual interface builders, like Storyboard in iOS, because Dart’s declarative, programmatic layout is easy to read and visualize.
-
Dart has a easy learning curve, because it has similarity with various other languages. It is the combination of the features of these languages that makes Dart so powerful.
At Flutter Interact, Dart was updated to version 2.7 with support for extension methods, character package and null safety preview. You can get more info from this article.
Hot Reload
In the native iOS app development, if we even make very simple changes like changing the color of a component, it will take at least 10 seconds to display the change onto screen.
Flutter’s Hot Reload allows the developers to only send the incremental changes of the source code to the running Dart VM, rather than running the whole code after each change. This enables it to make changes almost instant, and that also retaining the state of the app.
Flutter’s hot reload feature helps you quickly and easily experiment, build UIs, add features, and fix bugs.
If you haven’t yet tried out Flutter, just check it out once, at least in the name of Hot Reload. You have to see it to believe it.
Declarative UI code
Every component in Flutter is known as a Widget. The Flutter apps are created by combining these widgets (like building blocks) to form a widget tree. Even the final app we get is also a widget.
Flutter uses declarative UI.
In declarative style of programming, we are most concerned with what we want as the answer. Here, we as developers are not concerned with how we get there, simply concerned with the answer that is received.
That means Flutter uses UI as a function of state.
This also allows the Dart code to run on a single isolate.
Whereas, iOS development using Swift follows imperative programming paradigm.
In imperative style of programming, we care about how we get to an answer, step by step. We want the same result ultimately, but we are telling the complier to do things a certain way in order to achieve that correct answer we are looking for.
This also means Swift code runs across several threads and to maintain the communication between the components in iOS we have to use closures (callbacks), delegates, notifications, target-selectors, key-value observation, etc.
Swift uses a separate interface builder called Storyboard to design the UI of the app.
This often makes the code a lot complex to understand and reduces productivity.
As Flutter uses declarative code, it is lot cleaner and easier to refactor than the imperative style Swift code. Also, declarative code means that we are reasoning at a much higher level of abstraction as compared to imperative code.
Design Guidelines
Following iOS design guidelines in Flutter is really very easy. Flutter has a separate UI component library known as Cupertino Widgets. This contains all the widgets which follow iOS design guidelines by default.
With the introduction of Flutter 1.12, now there is no need to download each font from the Google Fonts library to use it in your Flutter app. You just have to include one package, google_fonts, and you will get access to the entire Google Fonts library.
Flutter 1.12 improved some of the Cupertino widgets and added complete dark mode support to them.
You can find the official iOS UI design tips here.
There is also a Google Codelab available for Building a Cupertino app with Flutter.
Dependency Management
iOS depends on some third-party tools for its dependency management system, like CocoaPods or Carthage. So, the iOS developers need to learn about these third-party dependency management tools.
Flutter uses its own dependency management system called Pub. The Pub Package manager is inbuilt with Flutter and it is easy to import new dependencies as needed for the app development.
You can get more info about how to use packages in Flutter here.
Add-to-app
Flutter can also be integrated to your existing iOS apps as a library or module. That module can then be imported into your iOS app to render a part of your app’s UI in Flutter.
As of Flutter 1.12, add-to-app is supported for the basic scenario of integrating one full-screen Flutter instance at a time per app.
A documentation for adding Flutter to an existing app is available here.
Testing
Apple uses XCTest as the testing framework starting with Xcode 5. The types of test that you can perform using XCTest are:
- Unit Tests
- Performance Tests
- UI Tests
XCTest is integrated tightly with the development environment of Xcode, so it provides easy-to-use and seamless workflow with other components and features of the development environment. But it has some performance and stability issues while running UI Tests on device.
Swift also lacks a proper mocking framework. So for mock testing, some of the frameworks that iOS developers rely on are Cuckoo & MockFive.
You can find a brief testing documentation for iOS here.
On the other hand, Flutter is very strong in terms of testing. It also has three catagories of testing:
- Unit Tests
- Integration Tests
- Widget Tests
The Widget test in Flutter is similar to component test or UI test of other frameworks. But Flutter runs widget tests as fast as unit tests, which gives it a huge advantage over the normal UI tests used in iOS. You can also use other testing frameworks like Mockito by using the mockito package in Flutter. For running Integration tests in Flutter, you have to include a package known as flutter_driver.
Documentation for testing Flutter apps is available here.
Conclusion
Flutter has become a really powerful framework and can’t be ignored anymore. Whether you love or hate Flutter, as an iOS Developer, you should definitely try out Flutter and Dart to understand their true powers.
Whether Flutter will replace native iOS, still remains a question. While we wait for this answer, it is safe to say that Flutter has a very bright future. Even if it fails to replace native app development, it has already proved to be the best UI design framework available at this point of time.
Why Android Developers should pay attention to Flutter🤔
Flutter vs Native Android
At Google IO 19, Android officially became Kotlin first for developers, which focused on improvements in terms of code compactness and readability. Rather than introducing new features, Google mostly worked on improving the developer experience across Android Studio and it’s tools. Also, Google launched Jetpack Compose to enable developers to create declarative UI, which requires less code, and it provides powerful tools and intuitive Kotlin APIs.
The biggest advantage that Flutter gives in comparison to native Android is the cross-platform support, i.e., you can use the same codebase for different platforms like Android, iOS, Web, Desktop, etc.
But can it deliver the same performance and stability like native app does? When it comes to cross-platform this is the most important question that all developers have in their mind. So, let me say that cross-platform apps still might not be as stable as native apps nor it can give the same level of performance like native apps in certain situations. But in comparison to other cross-platform solutions, Flutter is able to bridge this gap to a large extent. And, now after so many years of improvements, Flutter is able to reduce this gap to such a extent, that you might never be able to tell the difference between a cross-platform and a native app running side-by-side.
Now, the question comes, how can a cross-platform app be as performant as a native app? This is due to the excellent architecture of Flutter Framework and due to the language used by Flutter, i.e., Dart.
Architecture
Native Apps
In the native apps, whether it is Android or iOS, the native app code talks to the Platform to create OEM Widgets or for accessing various Services like audio, sensors, camera, etc. The widgets are rendered to a screen canvas, and events are passed back to the widgets. This architecture restricts the widgets to be reused across all platforms as they are OEM specific. And, this is the reason we have to write whole app for each platform separately.
Before moving on to Flutter, let’s checkout the architecture of another popular cross-platform solution, React Native.
React Native Apps
React Native apps are written in JavaScript, so to access the OEM widgets it has to use a bridge to talk to the Platform. This is where the bottleneck of this Framework lies.
So, the solution from React Native developers:
In order to architect performant React Native apps, we must keep passes over the bridge to a minimum.
Flutter Apps
Now, coming to the Flutter apps. Flutter solves the most challenging part of the other cross-platform frameworks, i.e. getting rid of the BRIDGE. Flutter does not use the OEM widgets, it provides its own widgets. Flutter moves the widgets and the renderer from the Platform into the app, which allows them to be customizable and extensible. This also helps Flutter to maintain the consistent 60 FPS.
Dart
Another reason that developers love Flutter is because of the Dart Language.
Dart is an object-oriented, class defined, garbage-collected language using a C-style syntax that trans-compiles optionally into JavaScript.
Some of the features that separate Dart from the other languages are as follows:
-
Dart uses AOT (Ahead Of Time) compilation, which gives the fast startup and fully customizable Flutter widgets.
-
Dart also uses JIT (Just In Time) compilation, which is the main reason that Hot Reload exists. I will talk about it in a bit.
-
Dart has a garbage collector built in the language. This enables Flutter to achieve smooth animations and transitions that run at 60fps.
-
Dart allows Flutter to avoid the need of a separate declarative layout language like XML in Android, or separate visual interface builders, because Dart’s declarative, programmatic layout is easy to read and visualize.
-
Dart has a easy learning curve, because it has similarity with various other languages. It is the combination of the features of these languages that makes Dart so powerful.
At Flutter Interact, Dart was updated to version 2.7 with support for extension methods, character package and null safety preview. You can get more info from this article.
Hot Reload
In the native Android app development, if we even make very simple changes like changing the color of a button, we have to wait for at least 2-3 minutes for it. Forget this waiting game in Flutter.
Flutter’s Hot Reload allows the developers to only send the incremental changes of the source code to the running Dart VM, rather than running the whole code after each change. This enables it to make changes almost instant, and that also retaining the state of the app.
Flutter’s hot reload feature helps you quickly and easily experiment, build UIs, add features, and fix bugs.
If you haven’t yet tried out Flutter, just check it out once, at least in the name of Hot Reload. You have to see it to believe it.
Material Design
Following material design guidelines in Flutter is really very easy. For using material design throughout your app, you just have to use the widgets from the Material Components library (by importing it at the beginning of a Dart file). All the widgets of this library are created by following material design guidelines by default.
More info for using Material Design with Flutter is available here.
With the introduction of Flutter 1.12, now there is no need to download each font from the Google Fonts library to use it in your Flutter app. You just have to include one package, google_fonts, and you will get access to the entire Google Fonts library.
Earlier it was very difficult to always follow the material design guidelines on native Android, but with the recent announcement of Jetpack Compose complex UI designs are much easier to achieve, that also with less amount of code.
Add-to-app
Flutter can also be integrated to your existing Android apps as a library or module. That module can then be imported into your Android app to render a part of your apps' UI in Flutter.
As of Flutter 1.12, add-to-app is supported for the basic scenario of integrating one full-screen Flutter instance at a time per app.
A documentation for adding Flutter to an existing app is available here.
Testing
Native android apps have three broad catagories of tests:
- Unit Tests
- Integration Tests
- UI Tests
It also has support for various testing frameworks like JUnit & Mockito for running unit tests, and Espresso for UI tests.
Android provides a full documentation for testing your apps.
Flutter is very strong in terms of testing. It also has three catagories of testing:
- Unit Tests
- Integration Tests
- Widget Tests
The Widget test in Flutter is similar to component test or UI test of other frameworks. But Flutter runs widget tests as fast as unit tests, which gives it a huge advantage over the normal UI tests used in native Android. You can also use other testing frameworks like Mockito by using the mockito package in Flutter. For running Integration tests in Flutter, you have to include a package known as flutter_driver.
Documentation for testing Flutter apps is available here.
Conclusion
Flutter has become a really powerful framework and can’t be ignored anymore. Whether you love or hate Flutter, as a native Android Developer, you should definitely try out Flutter and Dart to understand their true powers.
Whether Flutter will replace native Android, still remains a question. While we wait for this answer, it is safe to say that Flutter has a very bright future. Even if it fails to replace native app development, it has already proved to be the best UI design framework available at this point of time.
Bram De Coninck carried through an experiment where he created the same application simultaneously on native Android, native iOS, Flutter, Xamarin Forms and React Native. Take a look at the Flutter Versus Other Mobile Development Frameworks: A UI And Performance Experiment
What’s holding developers back
What are the most common objections for implementing new framework and how to potentially overcome these.
Dart is so new
It’s concerning because well, easy come, easy go. This breaks out into two discrete components, because DART is newer than other languages like C# or Java, and Flutter itself is still newer.
DART is quite a new programming language. Before Flutter came along, well, it doesn’t seem like it was doing that great. It was first shown in 2011, while Typescript was shown in 2012. Despite this, Angular, a Google product, was shipped using Typescript, a Microsoft product. Maybe there was a superb reason for this, but it seems weird that Google didn’t use their own language with their own product. I mean, it wasn’t even that long ago that sites were effectively declaring Dart as a dead programming language. According to that article, in 2018, there were 35 companies using Dart in their technology stacks in the world. That’s pretty low.
A new language in a project means the appropriate technical assistance in the team to continue to provide support for it. It’s not enough that just you know Dart, everyone in your team that is expected to support the mobile apps have to use Dart as well. To introduce Flutter into the landscape is to introduce change, and usually, people don’t love change.
Flutter is so new
Flutter went stable in December, 2018. And then we started writing apps in it and reached a level of nirvana hitherto unknown. That’s great, good for us, but what does it mean for your senior software developer?
It means that unless you hire someone that was on the team that designed Flutter, it’s probably pretty unlikely that you can actually hire someone with, say, five years' experience in Flutter. That’s pretty important — if you think about most job advertisements for software development roles, especially in roles where you are producing production quality applications. After all, we’re all super pumped to be using Flutter, but what would you do if a Widget was displaying incorrectly? And if it was introducing an app-breaking bug? Do you really know how the widget tree works and the rendering lifecycle, so you can diagnose these kinds of issues? I’ll tell you right now — I don’t. If I want something centered, I wrap it in a Center. If it still doesn’t play ball and its in a Column, I use mainAxisAlignment/crossAxisAlignment. If it still doesn’t work, I just accept how it looks. That’s okay for personal projects, but it won’t work in a workplace where there are actually requirements.
It’s not enough to just straight-up trust in the quality of Flutter, you have to prove that it is production ready to your boss. If your argument boils down to “I trust that the Flutter code base has no bugs because Google wrote it and it aligns with my personal beliefs”, then it won’t go well. I enjoy using Flutter but it does have some quirks — I dare say some of the more exciting ones we probably haven’t even found yet. At the same time, given the quality of the framework and the language, I believe anecdotally that those quirks, whatever they may be, won’t make me ditch Flutter.
So how long can we expect Flutter to be around for?
Nobody wants to be the guy that adopts a brand new language and framework only to have it fizzle out a few months later. So there’s some completely fair concerns about the longevity of Flutter. The reason that Flutter has the following and excitement it has today is because it has the blessing and support of Google. Of course, Google’s backing today is not a guarantee of that backing existing in the future. Google has a history of killing products that people use and love. Snazzy events like Flutter Interact, and the high quality of the learning materials like Widget of the Week are no doubt helped immensely by Google’s finances. What would happen if Google pulled their funding and support?
Fuchsia
Flutter forms the UI component of their upcoming Fuchsia operating system. In the context of operating systems, the UI is fairly important, correct? So if Google shut Flutter down tomorrow and completely abandoned it, they would have to have to come up with something else, get us all excited for that, and then implement it. It would probably push Fuchsia back quite a bit. One of the perks of having Flutter out now before Fuchsia lands is that Flutter apps will support Fuchsia as a target platform, so that means we have apps today that are compatible with an OS that isn’t even out yet. That’s a huge advantage. I mean, think about platforms that have been otherwise great, but nobody wanted to write apps for them, like Windows Phone? It seems like Google is in the opposite of that situation which is pretty good for them.
Testing in Flutter
Personally, I always struggled to write tests in previous mobile development frameworks. Comparatively, in Flutter it is a lot better. I won’t detail this here, especially because the Flutter website explains it quite well, but basically you have your unit tests, and then you have your widget tests, and then integration testing. Unit tests just test your individual functions to assert that they work correctly, whereas integration testing will automate a device from start to finish to check that your app works as expected. The real beauty, I believe, comes in the ability to write tests for your widgets.
Widget testing
As we know, everything in Flutter is a widget. You essentially compose these widgets to build your app. Now, you could just write unit tests to assert that your functions work, and write integration tests to do a full end to end test, and you would have a well tested, high quality application. But unit tests for functions and classes don’t lay your app out, while integration tests mean you need to spin up an emulator or a physical device to run, so they take a little longer.
Widget tests are kind of the happy middle ground in this landscape. When a widget test runs, it lays out your application and acts a lot more like your app would act like in an actual phone environment, but uses an implementation of the UI system that is significantly simpler than the traditional Flutter UI experience.
This means you can do things in your app, set text and colors etc, and check that the text of your widget is as you expect it to be. Bearing in mind, this happens at a speed roughly equivalent to that of a unit test, without having to run the test on a physical device.
Having greater test assurance while keeping the time it takes to run the entire test suite low is always a good thing. It also means you can potentially deliver more in a shorter amount of time, due to the tests not taking as long to complete. More deliverables in a shorter time means you are extracting greater value from your developers.
>> Take a look how easy is full-stack testing of Flutter apps with Codemagic
Everyone agrees that Flutter looks good on paper, but how can companies who still doubt Flutter be convinced that they should at least consider using it? Theories and opinions are one thing, but what we really need more of is proof of Flutter’s capabilities and performance.There’s not more powerful way to show the true value of Flutter by building the same app side by side.
Bram De Coninck carried through an experiment for his thesis where he created the same app five times, each time with a different framework. The frameworks he used were native Android, native iOS, Flutter, Xamarin Forms and React Native. During the second experiment I measured the CPU usage of the apps I created in the first experiment. In this article I will share the results of these experiments. Take a look at the results here
Implement a proper CI/CD tool
When you’re building a Flutter app or considering doing so, don’t forget about implementing a proper continuous integration and delivery (CI/CD) tool to help you build, test and distribute your app.
Building Flutter apps with Codemagic
Codemagic is the first CI/CD dedicated for building, testing and distributing Flutter apps.
You are required to connect your repository and Codemagic will build your Flutter app for both iOS and Android. Your tests are detected and run automatically. Once the build finishes, you will receive the build artifacts on your email and have them available for download in the app.
All you have to do is:
- Connect your repo using GitHub, Bitbucket or GitLab.
- Click Start your first build.
The first build is run with preconfigured defaults. After that you can take full advantage of the features and configuration options that we offer, including automatic code signing without Mac and app distribution. See how to set up Flutter apps on Codemagic to get started.
Wrap-up
Whether Flutter will end up winning mobile developers over or not remains to be seen. However, when you have already chosen Flutter as your SDK or decide to give it a try, we urge you to do it right and automate building, testing and distribution of the app by implementing a dedicated CI/CD tool for Flutter.