Code Heroes is a cross platform mobile app development company meaning 90% of our code is shared between android and iOS. We have been using Xamarin Forms for app development since 2015. Around that same time Google’s “Shy” project began, and in the years since has grown into the platform we now call Flutter; a platform seeing a frenzy of attention lately. We’ve decided to join in and make the transition. One of our core values is “pioneering” so we stay up to date with the latest technologies while also considering our value of “excellence” and choosing the most appropriate technology for an app, not just the trendiest. Flutter ticks both those boxes.
There is much information out there for devs interested in the benefits of Flutter’s design (some of which will be covered here). There’s less info though for devs interested in making the transition from Xamarin Forms specifically. Hopefully this is an insightful “Xamarin Forms vs. Flutter”.
First, some of the general benefits for any dev looking for reasons to switch, then some more specific differences between Forms and Flutter:
If you use Xamarin Forms, you know that performance can be a problem. You can make it fast, but the work to get there can be convoluted; creating platform-specific renderers that make you question why you aren’t working natively to begin with. Flutter is fast. It’s so much faster than Forms that performance and optimization have basically become a non-issue for us, even for the most complicated of views. This added performance and general flexibility have enabled us to be more ambitious with animations, transitions, and polish that Forms would have made needlessly difficult.
It’s worth pointing out that Flutter has prioritized performance since day one. The intent being to render a consistent 60/120 frames per second.
If you have ever developed on a platform capable of hot reloading, you will know it’s a game changer. Flutter has great hot reload support, preserving state while you make whatever UI changes you deem suitable – and even logical changes are smoothly accepted. The closest we ever got with Xamarin Forms was LiveXaml, which is highly recommended if you’re deep in XF XAML-based work. At the end of the day, it still pales in comparison to what Flutter offers.
You might be confused by this one – XF is open source too, no? That’s true, but debugging through the source is a hassle, to put it mildly. Debugging and exploring the Flutter source is a frictionless experience, and you’re welcome to make edits should you deem that wise (all hot reloaded while running!).
This is a common point of contention for those investigating Flutter, and it’s clear Dart hasn’t won the hearts and minds of developers given this survey. That said, for a .NET developer looking for an alternative to Xamarin, Dart is actually a blessing. The DartLang website describes the language as having an “unsurprising object orientation and syntax”, which is an interesting way to say that things are comfortably similar to C#. Our devs were ready to start writing production code in a couple days. Alternatives like React Native (using JS) were considerably less attractive.
Some structures in Xamarin are linked, for example the ListView and ListCell types. It’s more difficult than it should be to reuse your work on a Cell outside a List, or to populate a List with non-Cells.
Flutter doesn’t have this problem. Everything is a Widget, and Widgets are one of the most basic building blocks Flutter offers. Widgets do not control their layout, leaving you to determine how to layout anything, anywhere. Want a list full of buttons? No need to have cells wrapping them; just place them directly in the list. Want to re-use your nicely-styled cell outside of a list? Then just do so. This significantly speeds up work and improves code re-use across an app.
Xamarin Forms and XAML promise views that are more readable, and easier to structure. No having to jump back and forth across the different methods and declarations required to create a view in C#. A common pattern across our apps is forms.
The problem comes about when creating forms with variable number of items, and multiple optional fields. XAML encourages front-end dev that gravitates towards static structures. An already-constructed view requires significant restructuring in order to support dynamic content, both in terms of developer time, and the performance hit required to rebuild your views when changes occur.
It’s worth saying that Xamarin does not necessarily have this inflexibility if you write all your views in C#. The two ecosystems do not communicate easily however, and we ended up moving/converting away from XAML after being burned multiple times; a hybrid solution that brought the benefits of neither approach.
Flutter is designed around the idea of reconstructing the hierarchy whenever anything changes. Rather than getting an ugly white screen as elements are updated (a-la Xamarin), Flutter widgets generally handle this in an aesthetically pleasing way. In addition, many structures that naturally lean towards dynamic elements (for example, ListViews) have an option for providing child builder delegates, constructing those child widgets dynamically as the user scrolls or data is changed.
The loss of a markup language like XAML might be felt by some, but Flutter and Dart are written in a way that lays out elements in a similarly logical fashion.
At Code Heroes, we find the reactive capabilities of Xamarin lacking. For a long time, we have used ReactiveUI to better support the kind of reactive programming we are interested in, but at the end of the day we are fighting the platform. Flutter is innately reactive. The entire structure of its state management is built around the idea of tearing down and rebuilding the visual side of the app whenever state changes occur.
Xamarin still has some distinct advantages. An example is the environment – those fond of Visual Studio (as I am) will be sad to find it is not usable with Flutter right now. Flutter does integrate with Visual Studio Code nicely, so your mileage may vary.
We have also experienced some pain integrating certain aspects of our apps – WebViews and other services are supported by packages not yet mature. The community around Flutter is expanding rapidly, but Xamarin is hard to beat in this respect. Go into this new ecosystem with some willingness to roll your own solutions.
Flutter itself is remarkably stable, and in fact has given us less hardships (regressions, etc.) than Xamarin has over the same time period.
But what does happen when Xamarin or Flutter has a serious regression? What’s your fallback? Xamarin makes the task of rolling back your versions a painful experience – sometimes impossible, as old versions can’t be accessed anymore. The process often involves uninstalling, reinstalling, and then giving up.
At CH, we use Bitrise to manage our continuous integration. When the platform updates version images, regressions can become an especially dangerous issue; a ticking clock to reproduce and report before the old working image is itself replaced.
Flutter simply lets you pin your App to a specific version in one of the config files. Easy.
We are now a number of months into our second Flutter project and the increase in productivity (and programmer happiness) is remarkable. If your clients are demanding cross-platform alignment, Flutter gives the code sharing of Xamarin Forms, with performance much more competitive with native.
Amadeo, R. (2018). Google’s Dart language on Android aims for Java-free, 120 FPS apps. Retrieved from https://arstechnica.com
Flutter VS Code Extension. Retrieved from https://marketplace.visualstudio.com
Developer Survey Results. (2017). Retrieved from https://insights.stackoverflow.com/
ReactiveUI. Retrieved from https://reactiveui.net/