Flutter vs Apache Cordova: Developer Experience
The other day I caught myself thinking about Cordova. I wondered how it would feel to go back to developing apps with Cordova. How would the experience be different from how I feel while developing with Flutter?
Let’s dive into these two cross-platform frameworks and compare them in terms of the experience for the developer.
What is Cross-Platform Mobile App Development?
Cross-platform mobile app development is a process of software implementation for more than one computer architecture or operating system.
Cross-platform apps may be divided into two types. First are the apps that require individual building or compilation for each platform they support. Second are the apps that can be run directly on any platform without special preparation. For example, an app might need software written in an interpreted language or with pre-compiled portable bytecode for which the interpreters or run-time packages are common or standard components of all platforms (Wikipedia).
Usually, in cross-platform mobile application development, engineers try to achieve the following:
- Single code base: write code and implement all business logic in only one programming language. It will reduce the cost of mobile app development. “Write once, use everywhere.”
- The same look and feel across platforms.
- App responsiveness and performance comparable to native mobile applications.
Each cross-platform development framework addresses these issues in its own way. What follows is an overview of the unique developer experience with each tool.
Cross-Platform Mobile App Development Tools
In this article, we will review the current state of Apache Cordova and Flutter. We will also compare their abilities, provided tools and developer experience.
Apache Cordova: Overview
The architecture of the Cordova app is as follows:
This means a low entry threshold, which is a big plus for developers with a web development background. Also, there is a framework called Ionic built on top of Cordova that provides ready UI components and customizable design for your app. In addition, for mobile web pages development, you can choose among several CSS frameworks such as Foundation, Ratchet, Kendo UI, Topcoat.
Let’s see what it takes to start cross-platform app development. Cordova has a command-line tool that needs to be installed globally via Node.js package manager (NPM). And for mobile app development, you also need to install correspondent SDKs.
As Cordova CLI becomes available, you can easily create a new project with a simple command:
cordova create LearnCordova com.waverleysoftware.learn-cordova
This will create a project folder named “MyApp” with Cordova template single-page app inside it, and set the mobile app Bundle ID to “com.waverleysoftware.learn-cordova”. Before we can run it on mobile, we need to add a platform with CLI command inside the folder. Let’s take Android as an example:
cordova platform add android
This command will create a folder named “android” with the Android Studio project inside it. To run the project on an emulator or a real device, use this command:
cordova run android
Don’t make the mistake I did at first by not installing the Gradle build tool that has been required for building Android projects since Cordova-Android v6.4.0. At the time, I had already installed Android Studio, which is shipped with Gradle. It took a little while for me to figure out that Cordova requires this tool to be explicitly installed. Finally, I managed to run the template app in an emulator:
From there, it’s quite easy to create a Cordova project and start the development. A cool feature is that you have pretty much the same UI on each platform so you can use any CSS framework or build your own application style. Here are a few screenshots from Cordova-based cross-platform mobile apps:
The native WebView component could be called a built-in browser for each mobile platform. Every browser can show a webpage of any custom design written in HTML & CSS.
But there is a small not-so-obvious problem. Different versions of the same operating system and devices from different manufacturers could have custom WebView implementations. This could result in some HTML5, CSS or JS features not being supported, leading to inconsistencies in the webpage display.
What should be kept in mind is that heavily loaded interfaces can lead to performance bottlenecks. I’ve seen quite a bit of negative feedback about Cordova apps from developers and quality assurance specialists. Their complaints consistently revolve around the poor performance of these apps.
This is not an issue with Cordova itself, rather a limitation of its architecture and the WebView. The solution is to think about user touch interaction, UI responsiveness, and performance, and to follow optimization techniques.
I should also mention Cordova Plugins and explain how to work with them. Project dependencies in the Cordova native plugins and third-party plugins are managed by package.json and config.xml files in the project root folder. Plugins can be installed using the Cordova CLI command:
cordova plugin add <cordova-plugin-name>
Plugin source code will be cloned by CLI from NPM, github repository, or a local folder, and saved in the project as a dependency. Almost all official and third-party plugins can be found via plugins search page. The good news is that you can find plugins for most of the native mobile functionality you would ever need in your app. And you wouldn’t need to write a single line of native platform code.
It is different, however, if your app requires custom integration of native functionality or features rarely seen in existing apps (like WebRTC audio-video communication). Then, you are unlikely to find a suitable plugin. In this case, you will need help from native mobile developers for each platform respectively.
Here are some more cool features of Cordova:
- Simulation in browser, allowing you to simulate some native plugins and events in a browser environment (Android & iOS).
- App reloading upon the change in code (very useful during development).
- An official extension for VS Code that allows all of the above. It also debugs the code from the editor (breakpoints, debug output).
To sum it all up, here are the advantages and disadvantages of the Cordova platform for cross-platform mobile app development.
Apache Cordova: Advantages & Disadvantages
Apache Cordova Advantages:
- Stable battle-proven technology.
- Same app UI custom design on each platform.
- Extensive platform support (5 platforms).
- Satisfies the “Write code once – run everywhere” principle.
- Rich debugging capabilities, especially with IDE plugins.
- Multiple native plugins.
Apache Cordova Disadvantages:
- You must always think about the performance and responsiveness of your app.
- Supported “zoo of devices” would lead to platform- and device-specific issues.
- Code with platform-specific conditions (“if platform is … then …”).
- Third-party native plugins can have limited platform support or be outdated.
- The need for native development expertise in case of a custom native integration.
- Requirements installation to start the development with Cordova could be difficult for newbies.
Flutter is an open-source UI software development kit created by Google. It was initially released in May, 2017. As stated on the official site, Flutter is an app SDK for building high-performance, high-fidelity apps for iOS and Android, web (beta), and desktop (technical preview) from a single codebase. The goal of Flutter SDK is to allow developers to deliver high-performance apps that feel natural on different platforms. (Flutter: Technical Overview)
Even though it is a cross-platform apps development tool, the Flutter philosophy embraces differences in UX on different platforms: scrolling behaviors, typography, icons, and others
As a programming language, the platform utilizes Dart, which was created 8 years ago by Google for the development of the backend and web apps. Flutter runs in the Dart virtual machine, which features a just-in-time (JIT) execution engine.
The Flutter architecture consists of three main layers: Dart framework, C/C++ engine, and platform-specific embedder. Developers usually write code in the Dart language, run in a virtual machine using JIT compilation in development builds, or AOT (Ahead Of Time) compilation into native byte code for production builds.
For now, there are two platform-specific embedders in Flutter: one for iOS and one for Android. The web platform was announced quite recently with the release of Flutter v.1.12, but it is still in beta testing.
This layered architecture allows developers to:
- Use high-level widgets from ready-made widget collections of Material or Cupertino designs.
- Develop their own widgets using a low-level framework API.
- Write their own native plugins using C++ or reuse existing native libraries of iOS and Android.
- Achieve high performance close-to-native (thanks to the compilation of the native code).
- Hot-reload the application during development.
For development in Flutter, the smallest building block of the user interface is a Widget. App bar, drawer, text field, button, icon, columns or rows – almost everything is a Widget. The application UI can be built using these blocks simply by combining them as the widgets tree.
Flutter provides collections of widgets that follow Material design (native for Android) and Cupertino (native for iOS) right out of the box. This allows the developer to build interfaces faster. All these widgets are nicely customizable with themes or with their own properties. However, it might get complicated if the design developed by a UI/UX specialist does not follow Material guidelines and has customizations of standard material elements. In this case, you might face difficulties with the implementation of custom widgets based on Material Design.
Here a couple screenshots to illustrate the UIs of mobile applications built with Flutter:
Now, let’s examine the tools needed to start the development process. First, we need to install Flutter SDK. You can download it as an archive or clone sources from the Git repository. After you add a directory with binaries to the path environment variable, the command line interface will become available. There is a nice convenient utility under the flutter doctor command. It gives the output about the state of Flutter SDK, Android & iOS SDK state, manages emulators and connected devices. What’s more, it allows you to check if you properly installed all requirements to develop with Flutter and gives advice on how to fix them if not properly installed. That feature alone makes for a far more developer-friendly experience if you compare Flutter to Cordova CLI.
After installing native platform SDKs, we need to install plugins for the IDE. There are two extensions for VSCode that make the developer experience very pleasant: Dart Code and Flutter Code. They offer a great feature set:
- Rich code autocompletion, formatting, refactoring, snippets, etc.
- Linting of the Dart and Flutter code.
- Automatic fetching of dependency packages.
- App running and debugging on an emulator or a real device.
- Hot reload after code changes.
- Rich debugging capabilities.
To be honest, I have never had such a good experience of quick UI prototyping and debugging as with Flutter. Also, Flutter has web-based Dart Dev Tools. These allow inspecting the widgets tree, debugging renders and performance issues and much more.
To create a new project you should use the command:
Then, specify the output folder and other params like project name, description, etc. For example:
flutter create learn_flutter --project-name=learn_flutter --org=com.waverleysoftware
You do not need to add each target platform manually as is required in Cordova. Instead, Flutter automatically adds subfolders for iOS and Android projects in the project root. To run the Flutter apps, you can use the command:
However, first, you need to connect your device or launch an emulator. You can do it with the Flutter CLI as well:
flutter emulators --launch <emulator_id>
Below is a screenshot of how the template app looks.
A few words about third-party libraries. There is a pub.dev page, where all published third-party packages for Dart and Flutter are available. There are plenty of those: dates manipulation, internationalization, reactive asynchronous programming, charts, form builders, etc.
However, there are not so many Flutter-specific packages. The reason is that this cross-platform mobile app development framework is relatively new. Despite the hype, Flutter is still not widely used in production. And if you do find what you need in the collection of libraries, this library might have unresolved issues and lack maintainer support. So, if you need some customized widgets you should probably develop them yourself, or fork the repository of a library or a widget and make changes to it.
So what are the pros and cons of using Flutter for cross-platform app development?
Flutter: Advantages & Disadvantages
- Maintains the same app UI design on each platform: Material, Cupertino or fully custom design.
- Satisfies “Write code once – run everywhere” principle.
- Ensures native-like performance out of the box.
- Increases development speed with the help of ready-made widget collections, hot reload and framework tools.
- Offers rich debugging capabilities in VSCode and Android Studio.
- Provides static and runtime type checks.
- Allows a shallow learning curve for web developers, especially experienced with React.
- Continues to develop, adding new platforms and features, has an active community.
- The framework is relatively new and not yet widely used.
- Many third-party libraries and widgets lack maintainability (unresolved issues, pending pull requests).
- UI designs with deviations from Material and Cupertino are hard to implement.
In this article we have reviewed two cross-platform app development tools: Apache Cordova and Flutter. We have compared their strengths and weaknesses from the developer experience perspective.
When I look at Cordova in the past and now, I can say that many aspects have changed for the better. Today Cordova provides a much better developer experience than 6 years ago when it was a relatively new technology. Its stability and the usage of well-known HTML+CSS+JS stack definitely makes Cordova a good instrument for developers who want to write cross-platform mobile apps.
However, Cordova still requires developers to know web view performance bottlenecks and be able to handle them. It also requires writing native code when native custom functionality is needed. The installation of Cordova and all the requirements may cause difficulties and confusion.
Flutter, on the other hand, is a rising star among cross-platform app development technologies. It provides fantastic features to increase the development speed: easy installation, full-featured CLI, hot reload, advanced debugging with IDE plugins, widget tree inspector, collections of ready-made widgets and application performance close to native.
This feature set impressed me tremendously when I started working with the Flutter app framework. I believe it makes Flutter an excellent choice for those looking to develop cross-platform mobile applications. This technology is quickly growing in popularity and has an active community. Sometimes it is difficult to find quality libraries that meet your search criteria, but that will change very soon given the speed of Flutter’s growth.
Which cross-platform app framework do I personally prefer nowadays? Of course, I would choose Flutter, but Cordova is always an option. What would you choose for your next project?