What we’ve learned using Flutter for commercial cross-platform app development
Whether you’re a developer or a product manager thinking about how to create digital experiences for your customers, you have probably heard about Flutter. This new cross-platform development framework from Google is quickly gaining popularity. And it’s easy to see why. Besides Google’s heavy investment, Flutter is a programming framework to rule them all — allowing developers to build apps that work across mobile, connected products, and even desktops — reusing as much as 90% of common code.
Flutter is getting the attention of many companies and development teams — and some are now building commercial apps with the framework. That includes our team here at ArcTouch, as we’ve always been fans of cross-platform development tools that can help us and our clients deliver lovable apps more quickly and efficiently than before. We’ve been Xamarin developers since 2013 and are looking forward to using Flutter more and more. In this post, we’ll share some of our learnings about Flutter so that you can decide whether to use it in your next mobile or IoT project.
One development team. One codebase
One of the biggest advantages of using Flutter, as with any cross-platform framework, is that you can have a single development team using a common codebase. For app development, this means that instead of having separate iOS and Android teams, you can create apps for both platforms by having Flutter developers working in a single code repository.
Being able to have this work environment not only enables more efficient app development. It also helps streamline the ongoing maintenance of different apps and new feature development. In theory, it’s possible to reduce the cost to maintain the project by 50 percent — or develop twice as many features using the same sized development team. In practice, however, you still need some native platform development — at a minimum, the app icon still needs to be created natively, and some apps might need some minor final tweaks within Android or iOS.
Flutter has a short(er) learning curve
As with any development technology or programming language, to build apps in Flutter you need Flutter developers. However, from our experience, Flutter’s learning curve is shorter than most. We’ve seen that a developer from most backgrounds can learn the basics for Flutter in 3-5 days (of course, like any technology, it takes more time to learn the nuances).
You can add Flutter to existing apps (soon)
If your company already has an app and you want to explore the framework, you soon will be able to try Flutter. Google is developing a feature that will allow developers to import a Flutter module inside of an existing native app. The company has already shared the preliminary results to add Flutter to existing apps, so users can test it and provide feedback. However, Google has said that this tool is not yet ready for commercial development — and expects to release the first stable version by the end of this year.
Dart makes Flutter easier
In fact, Google’s team spent a lot of time to create learning paths on the Flutter website, to help onboard developers from varied backgrounds, and comparing other programming languages with Dart. This collection of tutorials is some of the best documentation to get started with the Dart programming language.
Flutter’s hot reload is … hot
One of the best things about Flutter is the hot reload, which allows developers to almost instantly see results from any changes, in many cases without losing the app’s state. This is such a boon to developer productivity compared to the native platforms. Now you don’t have to wait for 5 minutes for the build cycle to complete, only to realize you missed something and have to build it again. With Flutter, you can put your layout together in small blocks, and instantly see the outcome. You don’t need a preview screen of your layout, nor even a layout editor. It’s just faster to hot reload and see the result in the running app.
However, based on our experiences, the hot reload doesn’t always work as expected. Sometimes after changing the behavior of a component the engine has to rebuild the app from the top. For those cases, we’ve used a hot restart, which is still faster than the traditional native build and provides a new app instance, from which you can hot reload again.
Flutter isolates the engine from the native UI
Flutter’s main value proposition is to enable developers to “design beautiful apps” with native performance. To deliver on this promise, Flutter isolates almost everything within the engine from the native platform, including all native UI components. This decision has a tremendous impact on the final performance because the most costly operation in cross-platform apps is switching between the framework and the native components. Because it’s isolated, the Flutter framework can perform at full speed, delivering a native-like experience.
Flutter UI widgets help streamline UI development
Because Flutter doesn’t use native UI components, the framework needed a method to render UI on the screen. So, Flutter builds its own UI by using an “atomic component” — meaning that everything that will be displayed on the screen is built from the smallest possible building block. Flutter does this by using widgets. In a Flutter app, every component rendered in a screen is a widget. From the most simple text to the most complex animation: everything is a widget. Every UI component will inherit characteristics from the Widget class and add its own functionality.
For example, the Text widget (which displays text on the screen) has the following parents:
- Text → StatelessWidget → Widget. This pattern allows the framework to render (draw) everything on the screen with the same process for every component, once every UI component is a widget.
The Flutter team created an extensive library with all sorts of widgets, some more customizable than others — allowing developers to reuse, extend and customize them in any way.
Using Flutter widgets is like building LEGO® structures: You just need to fit the basic widgets together. If you need some very specific behavior, you will need to implement your own widget. In a recent project, we had to build a custom widget from scratch to match some specific behavior. It was pretty easy to implement and we are now able to re-use this widget in future apps.
Because of the way Flutter implements its widgets, developers can manage layout components and their effects as a single entity, without having to worry about platform-specific behavior. Flutter makes automatic adaptations to match each platform convention. For example, scrolling a list is different in iOS and Android, but you won’t need to implement one list for each OS because the list widget already knows which platform the app is running and handles that for you, out of the box.
Flutter makes animations effortless
Because you can have a widget that has layout components and animations in the same place, developers can embed animations or screen transitions directly in the widget tree. That makes the creation of complex animations as easy as creating a button. In addition to the really fast Flutter rendering engine, apps now can have any kind of animation with 60 frames per second — including the whole screen, rotating, applying zoom, any other predefined animation. The range of possibilities is almost infinite, enabling developers to work alongside designers to create innovative layouts with custom stylings and exciting animations.
Flutter simplifies phone compatibility
Even though the Flutter team focused on providing a great set of tools to build UIs, that’s not enough for modern apps. Today, connectivity in mobile requires apps to play nicely with a variety of phone sensors and hardware. With Flutter, you can leverage any hardware or internal API from the native framework without using wrappers or building additional layers to create links between the service and your app. Instead, Flutter offers a message system to communicate with the native platform. A system library includes a growing number of tools to handle this communication — plus there are open-source tools from the community.
Google also developed platform channels as part of this communication system, so developers can write their own implementation to access everything in the native realm. At ArcTouch, we’ve used platform channels to give us complete control over native APIs — from Android and iOS — allowing us to write the specific customization we need to manage sensors.
Flutter’s not perfect (yet). Some things you should know:
The Flutter ecosystem is growing really fast, but it takes time to create a solid cross-platform framework covering everything native platforms include. One example of this is defining new application flavors for different release configurations — for example when you want to publish your app to the App Store or send it to QA. That’s one of the more recent problems that we’ve faced here. The Flutter website doesn’t cover how to achieve multiple release targets.
This problem gets bigger if your company uses a continuous integration (CI) tool (such as Jenkins) to publish your apps to the stores. There aren’t many resources about configuring different CIs with Flutter. And if you need a specific flavor to build in your CI, you will have to spend some time to figure out a custom solution — which for our development projects has been an investment in time from both IT and engineering to get it right.
Another issue that has been addressed recently is error messages from Flutter. Prior to version 1.9.x (released on September 10), it was hard to find out what error messages meant. Now, most new error messages explain exactly what is wrong and how to fix it – a welcome improvement for cross-platform app developers.
Last, if you want to build Flutter modules to integrate with your existing apps, you might find some problems importing multiple modules. If you want to import Flutter in a native iOS project, the Flutter SDK has to be installed — from the iOS developer machines — to the CI/CD. Also, there’s no direct way to import more than one module in a native project, so you need to build everything that you want inside of a single module or use an umbrella/glue project.
The first option is acceptable if you want to import your module in a single native project.
If you want to import the Flutter module in different projects, you will eventually import unnecessary code, because everything is coupled, resulting in a larger app size. If you want to modularize your projects, importing only the features you want, you will have to create a second Flutter module — the umbrella module. There, you can import all the other features, then import the umbrella inside of your existing app. We chose this way and had to handle the communication between the modules, passing through the umbrella to finally get to the native app. We know this functionality is still in preview, but we’ve provided detailed feedback to the Flutter team and they already have plans to fix these problems.
Flutter vs. Xamarin vs. React
The most well-used mobile cross-platform frameworks, Xamarin and React Native, have been in the market for quite some time, while the first stable version of Flutter launched just 9 months ago. All three frameworks have similarities and differences, pros and cons, and we’ll be comparing these soon in an upcoming blog post. (Follow us on Twitter, LinkedIn, and Facebook to get notified of new posts!)
Flutter everywhere (eventually)
Google’s big plans for Flutter include allowing developers to build the same app to use for mobile, web, desktop and the IoT. This is still a work in progress. Recently the Flutter team merged the web integration with the mobile framework, so developers can now turn their mobile apps into websites, using the same codebase. It is not stable yet, but you can already try this functionality. Also, you can already build Flutter apps for Windows, macOS, and Linux — but for that, you will need some extra time because it’s not fully integrated yet.
Even though Flutter is an emerging technology, it already solves big problems for cross-platform app development without compromising the user experience. And the framework continues to grow at a rapid pace. That means broader support, more closed issues, and a wider variety of available packages and plugins. Because it’s an open-source project, many developers can help to improve the framework, implementing features, fixing bugs or even giving ideas for new features.
The Flutter Github’s repository is among the 10 most starred repositories, so you can rest assured that there is a community behind it and Flutter is not going to mysteriously disappear. The number of closed issues can confirm that: more than 17,000 and growing. From our real-world experience, the framework is ready for commercial projects and despite some risk, the benefits of using Flutter for cross-platform projects outweigh those risks.
Need help with your cross-platform app development project?
From native app design to cross-platform development, ArcTouch has been building mobile and connected experiences since the dawn of the app store. Learn more about ArcTouch’s app development services and contact us for a free consultation.