by Łukasz Kosman and Jakub Wojtczak
We are sharing the insights after making the first 10 commercial apps within the last 24 months during which we’ve spent some 17.193,00 hours on Flutter projects.
After reading this article you will learn:
- What are the reasons to choose Flutter? What impact Flutter has on budget and stabilization?
- Is Flutter ready for enterprise apps?
- How is Flutter performing in comparison to Xamarin?
- Which projects is Flutter suitable for?
It’s been two years since we’ve started the development of our first commercial application in Flutter at LeanCode in July 2018. When I first learned about Flutter, although it was promising, I remained skeptical, mostly because of the negative experience from our recent investment into Xamarin. Since there is always some new and exciting technology our team wants to bring to the project, we challenged them and asked for the proofs on how this can bring real value to the client. This was an agricultural project, dealing with herd management. There is one interesting artifact, typical for this industry, which is widely used by the breeders to calculate the demand for the barns and our team felt that this is a great insight from the UX perspective.
Within two days they proudly showed the Proof of Concept demonstrating how easy it is to build an animated wheel giving you a great and smooth experience. Eventually, this has evolved into the full-scale animation which you can see here:
With this delighter, I was convinced that Flutter is worth experimenting with.
Initially, we didn’t want to commit ourselves 100% to Flutter, so we kept the React Native projects in parallel. When faced with writing our first implementations of Google Maps without official support from the Flutter team, I felt that this pessimism was justified. You can learn more about the experience of writing this first commercial application in Flutter and related difficulties here. Eventually what we have delivered was a relatively simple application, with less than 40 views and costs below 500 hours of Flutter development.
Once we’ve delivered this first application and collected a five-star review from our client we thought that we should start to recommend Flutter more actively to our clients since the beginning of 2019. From May 2019, we decided that Flutter will be our no.1 choice when it comes to mobile technologies and we will cease our involvement in developing apps on different frameworks.
Since then we’ve delivered more than 10 mobile products in Flutter and dozens of MVPs/PoCs. Now, it’s time to draw the conclusions.
Flutter is quicker.
And we are not talking here about the theoretical approach, although this is interesting as well (find the paper by Bran De Connick here). We had a unique chance to rewrite the apps from both Xamarin (client-facing mobile app) and ReactJS (restaurant manager facing web app) and results were comparable. It took us 67% of the time in comparison to Xamarin (667h vs 987h) and 69% of the time needed to create the app with ReactJS (486h vs 704h) for the very same scope using the same API on a backend side. Stop and think about those numbers for a moment. This is the ultimate answer to how to build the mobile application quicker and cheaper. With the economic downturn, it has never been more important to deliver new digital products on time and within budget. It can also mean that for the very same budget you can deliver a 50% bigger backlog. Imagine yourself as a product owner working on the priorities for your development team being able to move the budget barrier 50% further.
This will give a great boost to both the creativity of your team and the quality of the work they are delivering. For a detailed analysis of the GastroJob case have a look at our talk from Flutter Europe Conference here or check our case study here.
90% of the code on average is shared between iOS and Android.
90% of our code is not written twice for both native platforms. 90% of the time is saved in comparison to native app development and plenty of creativity is released due to the coherence and team being united around one goal instead of being divided into two native streams. Beyond sharing the business logic and user experience, we can use plenty of ready-to-go libraries, which bring additional benefits. Firstly, they can speed up the development process by providing commonly used logic for many different things used within the app (e.g. communication with the server (HTTP client), push notifications, secure storage, databases, animations, etc. ). Secondly, it is easier to integrate with many popular services (e.g. Firebase, Maps, Payments, Social Login, Analytics, Crash Reporting Services, etc.). Therefore you have to write code twice (separately for iOS and Android) only if you’re writing custom platform-specific code. Yet, even then, bridging between Dart and native code is fairly easy which is explained later in this article.
What is more, there are even bigger savings when we take into account the quality factor which makes the app cheaper also to maintain in the long run. Matter of fact has inspired us to investigate all projects built in Xamarin, React Native and Flutter to search for the pattern and what we have discovered is that Flutter projects typically need 8–10% of the time spent on bugs in comparison to React Native with the range 7–14% and Xamarin 11–23%.
Cooperation with UX/UIs has never been so good.
Something clicks on the cooperation between UX/UI Designers and Devs during the Flutter projects. Might this be for the reason that they don’t need to make this tedious native adaptation and they set their creativity loose. Yet, the same would be expected from the React Native team experience, and this is not the case. When we dug a little deeper, we discovered that Flutter brings pure joy for devs who can write beautiful interfaces, which previously were associated with an extra burden that slowed down the pace. Therefore, they were more willing to cooperate and we’ve observed the pair programming sessions started to happen with designers making the live experiments hand-in-hand with devs. After several such interactions, thanks to the robust theming engine, teams were able to come up with an adaptable design language for the app which not only looks great in Figma or Adobe XD but also gives the best possible user experience and the feeling of coherence and proper design order. How this coherence is present over the lifetime of the project is also interesting. Previously when UX/UI Designers were reviewing the product on the demo session they had most of their comments at the end of the project, changing their minds or simplifying things after the hands-on experience. What is unique about Flutter is the fact that at the end of the project the involvement of designers is completely fading away, as they did their job early in the beginning during design loops of trials and errors. This also means that the refinement of subsequent sprints takes less time and this continuous cooperation is reflected in the stable scrum pace of next releases.
Animations are easy and affordable.
Not only is it easy to implement some static views in Flutter, but it also provides great new opportunities when it comes to animations. This brings this UX-DEVs cooperation to another level making nice transition effects accessible as never before. So far that was typical only for the big-budget projects. Nowadays, thanks to Flutter, this is accessible to all developers. It happens because Flutter renders on bare metal, directly on the canvas with full control over the drawing which enables us to create the pixel-perfect images on all platforms without additional conditional formatting as it is the case of other cross-platform frameworks. When drawing for example with React Native, you are based on the default views which can alter the appearance of your new controls, therefore, building a smelly code, which is platform dependent and directly in contradiction to the approach that the shared code should not take into the platform where it is deployed.
Flutter apps are much lighter.
This is worth considering when facing the PWA business choice which proves how easy it is to add the shortcut on your phone to save the website as if it was an app. Let’s not comment on the user experience, but only on this burden of downloading the app. Yes, this is not effortless in both cases. The best PWA websites according to the SimiCart Blog require users to download from 4.9MB up to 11.6MB on loading. This is far lower than the average size of our Xamarin apps which is 25MB, even lower than the average for our React Native 32MB apps, but very close to the Flutter average which is 11MB with the range of 9–14MB for all our Flutter apps (just pay attention that those numbers are not directly comparable, though they highlight the pattern). You have to admit this (11MB) is extremely low for the native application experience, for the smooth look and feel, rapid reactions, and all services typical of native apps like push notifications, etc. This means that there are no barriers for the user to download the app and start to use it as efficiently as possible with all plugins and integrations. This also means that apps are more performant because they can execute similar tasks with smaller code. This boost in performance translates directly into those milliseconds that give you the quicker experience in cold loading of an app, animations, CPU and memory usage as compared to other cross-platform frameworks (actually when Flutter can give the better cold app start even in comparison to Swift/Kotlin native apps).
Native code is accessible when needed.
What is great about Flutter is the fact that the mobile team is more eager to go down to the native code and write some Kotlin/Swift packages as they can have a full control over the native implementation, which was not the case for example in Xamarin where the final code was generated in an isolated black box. Bridges to the native code are also more powerful because they are completely transparent and therefore more friendly for developers who have transferred from the native environments. Thanks to this approach this is relatively easy to implement specific features like local payment providers or some niche complex library. What is more, even advanced features requiring biometric algorithms for face recognition or fingerprints check are smoothly running on Flutter as it was showcased in the banking app developed by ING for Business in Flutter presented during Flutter Warsaw Meetup by Jakub Biliński (link).
Proof of Concept in Flutter is easy.
The ease of integrating with the native code brings additional benefits when we need to build the Proof of Concept in order to check the Riskiest Assumption Test.
This means that before the client decides to sign the contract for the whole project we can build the smallest possible app which answers the most critical business or technical question. This is the point, where we cannot overestimate Flutter capabilities. Every time we are timeboxing such initiatives to two days of development, trying to find out what can be achievable in such a short period. So far we were experimenting with a variety of PoCs ranging from AR supported image detection systems (below),
through whiteboard drawings and advanced animations.
Building a rapid PoC not only enables us to showcase the speed of development but also helps us to provide more accurate estimates for the final project.
DEVs are happy.
From the perspective of building the internal team, Flutter proved to be a good choice. Initially, there were few Flutter developers because nobody had professional experience. Yet, what was different in comparison to for example Xamarin where developers had a C# background, in case of Flutter all candidates were already mobile developers transferring from the native, mostly Android, background. As Flutter became more and more popular and thanks to the very active community, which is organizing regular meetups and webinars, the pool of available candidates grew exponentially and nowadays there is a substantial number of professionals looking for a job in Flutter projects who are willing to change sides after years of native app development. Thanks to the well-documented Flutter code and the availability of additional libraries that are driven by the community it is fairly easy to make such a transfer. Therefore some companies, who were previously having their independent mobile teams are investing in aligning them around Flutter. At LeanCode we were even organizing Flutter bootcamps, three-day-long training programs taking place at the lakeside to give the hands-on experience, and select the best candidates for the intensive, two-month-long study program, where learning Flutter was accompanied by doing some non-commercial projects. We were surprised to notice that after 9-weeks of training developers were ready to work side-by-side with their colleagues who started coding in Flutter from the early days. Such a short learning cycle proves that making a choice to switch from the native app to Flutter from the business owner’s perspective is not a revolution but an evolution in which their internal team can take an important part.
Making the right decision regarding your technology stack can have a lasting impact on your business and personal career. Yet, rarely the choice is so simple. Flutter already became an unstoppable movement, a force to be reckoned with and it is still growing and expanding towards very conservative industries with extremely high-quality standards like banking or insurance (with examples like NuBank, ING, and AXA to name a few).
If you take into account that this happens even before Flutter for Web or Flutter for Desktop are released in a production phase, this shows that Flutter for mobile is delivering enough value to compete on this very advanced market. Whatever industry you are working for, the times for early adopters are gone, and we will soon witness the arrival of more and more mature players entering the Flutter ecosystem. And I hope this will allow us to share the lessons learned from those implementations in the next year summary after making another 10 great apps in Flutter.