Four years ago, Pinch made the decision to adopt Flutter as a dedicated team alongside their existing native Android and iOS development teams.
Thomas highlights in this blog how Flutter, unlike other cross-platform tools, does not use web pages or bridge to native components but instead provides a canvas to draw anything you want on it. The Flutter engine, therefore, optimises performance for smooth animations and responsiveness, making it possible to run on various devices. Thomas also discusses the evolution of Flutter projects at Pinch and how the team started using BlocProvider, a bloc architecture combined with rxdart, to provide streams of data for input and output. Curious to read more, check out the blog!
When I first started doing mobile development back in 2014, I could never have guessed ending up as a tech lead of a cross-platform solution. I started out as an Android developer, fiddled around with the likes of iOS and Windows Phone in the early days, but stuck with Google for the long run. I did try out Xamarin at one point, and within Pinch, we even did React Native for one of our clients, but both solutions missed that native touch, the look and feel, the developer experience. The cross-platform tools always had some quirks.
It was after a year or 2 at Pinch that I saw a first glimpse of Google’s UI toolkit: Flutter. Our Android lead fiddled around with Flutter during a hackathon, showed his findings, and was impressed, but not convinced yet. It was still Alpha back then, so we kept our eyes on it and tried it out again when it was (close to) stable. I managed to team up with one of my fellow Android colleague, John van der Vaart and for 2 days we tried to rewrite an existing app in Flutter, with zero knowledge, zero experience. After 4 years I can easily say we could’ve done way better, but back then we were surprising ourselves of how easy it was to pick up Flutter, how fast we saw results, how the look and feel would fool you to think it was native instead of a cross-platform tool, and how the developer experience was so nice! Coming from Kotlin we were quite spoiled, but even though Dart felt like a step back compared to Kotlin it was easy and nice to work with! There were similarities, and a massive potential.
In the end, our demo triggered the management, and that got the whole Flutter ball rolling. Pinch has always been a native company by heart, and even though we keep trying new ideas and give things like React Native a chance, they always end up showing that nothing is even close to native mobile apps. They couldn’t ignore the progress we made in just two days though, and the look and feel was so good it was hard for them to see this wasn’t a native app. So we found a client that was willing to take this adventure with us and we got our first production app live back in 2019! More clients followed, and now Flutter is a dedicated team within Pinch, next to the native Android and iOS development teams we always had 💪
So why is Flutter there to stay?
Cross-platform solutions are not new within the mobile development world. We started out with web variants like Ionic and Cordova: nice and easy, especially when you have a background in web development, but far from the native look and feel. These solutions have always been an easy pass for Pinch, simply because we would never get that quality app we always promise to deliver.
So why is Flutter so different from these other tools, why is it giving us the confidence as a native-first company? Flutter does not use web pages, or bridge to native components. Instead, Flutter just gives you a canvas and the Flutter engine will draw anything you’d like on there. Everything happens within the Flutter framework! This is exactly why Flutter is also easily able to run on other devices: mobile, desktop, web, smartwatches, embedded systems, as long as we have the Flutter canvas in place it will be similar to any other platform from there on! (yes, this is a very simplified view on device support, sorry Google 🤓).
Apart from the UI, running everything in an engine dedicated to Flutter also means performance is optimised as much as possible to give you those smooth animations and responsiveness native apps are usually best in. Win/win!
And let’s not forget about the developer experience: debugging is as you would expect from native, we can even use a powerful IDE like Android Studio for development, and Dart is really evolving as a programming language, getting up to par with the likes of Kotlin and Swift.
Started from the bottom
We’ve come a long way with Flutter projects since 2019. The first thing that comes to mind when thinking of how Flutter development and our projects evolved is a pretty hot topic within the Flutter community: architectures.
We started out with bloc, or rather BlocProvider. Combined with rxdart we came up with something that looked similar to what we were used to on Android: ViewModels and LiveData. A Bloc was a simple class, extending or implementing nothing at the time, and contained subjects to have streams of data, both for input and output. BlocProvider then provided these blocs to your widget tree, much like how you would now use blocs and cubits. We used it this way in our first few projects, and it worked pretty nicely, nothing to complain! I did check out other stuff: Provider, Riverpod, GetX, but those never really clicked in my head. I did use Redux at one point for one of our clients, which also didn’t click for quite a while 🤓 But that did give a better form a stability to the project, separation was clear and code was fairly easy to test. In the end, we decided to go for the bloc-pattern we have nowadays, mostly using cubits instead of blocs, and still liking it a lot.
Any other highlights in our Flutter journey? Looking at dependency injection we started out with GetIt, which is more of a service locator, but alright. We started using it in our very first project and are still implementing it in the latest, great package! Networking is something we always did using Dio. Later on we added Retrofit into the mix, and we’re now moving to the Flutter Favorite Chopper. The last thing I’d definitely like to highlight is Melos: a tool to easily manage multi-package projects. Our projects tend to be split up in a clean way: presentation, domain, data, data sources, etc. Putting these in separate packages improves separation, Melos really makes it a breeze to manage all those packages. I would recommend it!
Here we are
So what does Flutter still have in store for us after 4 years? We see a lot of improvements: a new rendering engine, 3D support, improvements for Flutter web, support for new architectures, and the constant improvements of Dart, but what’s in it for us?
It’s hard to tell what the future looks like: I will always add Google’s Fuchsia OS to the list since Flutter supports it, but who knows when that will come to more use. At least we saw a glimpse of it with the Nest Hubs, right?
Component-based development might already be a thing and will continue to grow in my opinion. This will be of great use, especially for larger companies that have multiple apps using the same components, styling, or whatnot. By extracting a simple feature like a login flow or your UI kit into a separate, self-contained package you can reuse it across your apps: Flutter, native, web, you name it! Create once, maintain once, less work, more consistency 👌
Last but not least: I think I’m also curious about the 3D support that was shown off at Flutter Forward 2023. I’m not sure if game development in 3D will be a thing with Flutter, but what about Augmented Reality? 😏