Flutter, the web, and progressive web apps

Why Flutter?

A lot's been written about the virtues of Flutter and a lot of these virtues are the same set of promises from all previous cross platform frameworks. Is this time really different? In short, yes! Flutter has changed the game, a bold statement... so let's break down why.

I've been writing mobile apps for over 20 years, I've written for Palm Pilot, Symbian, Pocket PC, J2ME, iOS and Android. I wisely skipped Windows Mobile ;) In this time, at the start of every project I've reviewed the cross platform options available to see if we can get more bang for buck. More often than not, they sound compelling but fall apart the more complex the project gets. Some have been great but you could always tell the cost in app quality and feature support. Even with this, I've been a huge proponent of the modern web. I love a well written SPA (single page application), whether it uses Angular, React or VueJS. I also deeply jumped in on the PWA (progressive web app) bandwagon with the promise of frictionless installs and native like experience. The quality of these apps are now nearly native, and cross platform tools do provide a nice developer experience. Trouble is, there was always a 'but' with this approach. 

It's always frustrating that your app isn't as good as it could be. And the tooling, whilst improving fast, has always felt compromised for the task at hand. At the end of the day you can't hide from the fact that this approach is ultimately 'faking' it. It can be close, but dig deep, poke, or ask too much from your web app and the cracks will show. 

Flutter is different. It owns every pixel of the screen and paints them natively. This completely removes the JS (JavaScript) bridge of old, whilst opening up opportunities for so much more. Once this is fully grasped, the possibilities are amazing. Want Android 10 UI on an old phone, no problem. Or iOS components on Android, sure! Flutter matches the native UI components pixel for pixel, so in every sense of the word, they're the same. In hindsight, this seems so simple, in reality it's a massive achievement by the Flutter team. But for me, native looking apps aren't where it's at. Most of my apps are bespoke UI anyway. It's the best performance, freedom to experiment, enjoyment of coding (you make better apps if it's fun) that I care about. Flutter's approach means we can have our cake and eat it. We get truly native performance, native UI components if you choose, but also the ability to tweak, modify or create any component you like. It's not so much a question of whether it's as good as native, it's that and so much more.   


There's always a but... but what about the web? I've got so used to working around the compromises of web based cross platforms that I've started to take for granted the advantages the open web can give. What if you want your cross platform app sent to a client via a link? Usually, no problem, it's web based after all. Don't want to have to publish and manage app stores? PWAs (progressive web apps) to the rescue. Need it on a desktop? Electron has your back. The web is so ubiquitous that you can be sure if you need to run your app somewhere, you can normally install a browser engine to do so. But Flutter is a mobile framework, it creates binaries for iOS and Android. That's where it's native goodness comes from but no way they're running on the web.  

Back to the future

We all know the web is the future, so how do we get back? Luckily, Google always had the intention of Flutter running on multiple platforms. The web is very much a platform they had in mind from day 1. However, they started where the traction and biggest pain points in modern app development were. In its early form Flutter focussed exclusively on mobile (Android and iOS). But the unique approach of Flutter's architecture always meant platform support could be expanded out at a later date. If Flutter could achieve the seemingly impossible of creating a Flutter runtime for the web, we as developers would get web support for free at some stage down the line. The situation is the same for desktop with MacOS, Linux and Windows Flutter runtimes all at varying stages of development. 

Flutter has now officially hit beta stage for web support. I've trialled each of the pre-beta web releases and had been pleasantly surprised, but there was clearly a way to go before the DeLorean was ready. Once it hit beta, I took Marmoset, a major project of ours with over 40K lines of code, and started the task of getting it to run in the web. 

Add plutonium

For web support I needed to do two main things:-

1) Find all places in our app that use native plugin code. In our case it was mainly Maps, Firebase and Cached Network Images. 

2) Ensure all UI was responsive. 

For the plugins, I took the approach of refactoring to make sure all access went via a Factory. The Factory would decide at runtime to create a native plugin class or a web compliant class. For example, for Firebase I checked the platform at runtime and would return the Flutter native plugin if on Android or iOS. Otherwise, I would return a Dart wrapper around the JS client library. This approach worked seamlessly. 

For the UI, Flutter makes responsive layout pretty easy and the app was already written to manage a wide set of screen sizes. So this wasn't really an issue. If you need help see here

PWA support

Once web support was back in place, it seemed sensible to add PWA support. Essentially, we're back to running a website, so I could fall back on comfortable PWA techniques as you would for any site. Icons, manifest and service worker were added. All worked as expected and our Flutter app was now running in the web, as a PWA that could be installed to your phone or desktop. Once installed, it runs like a native app, which is where we started! Feels like we've gone full circle. I used to turn web based code into PWAs and wrap them to be delivered in the app stores. Now, with Flutter I can start with a native app, and with a few steps, convert to a web based app that can be delivered as a PWA. 

Potato potarto

Yes, it all sounds like potato potarto. Can't we just call an app an app and be done with it? No, I don't think so. 

Flutter has been built from the ground up to run optimally for each supported platform. You can expect 60 fps on mobile without issue. Its unique architecture allows native to mean native on each platform it runs. I'd argue in many cases it can run faster than native due to the framework owning every pixel. It's the same reason games engines are written, they need full control for best performance. Flutter does this on Android and iOS and it provides you, as the developer, a better chance of a perfect animation than any other way I've seen. 

On the web, Flutter adopts the standardised web where necessary and it makes sense to do so. But when it needs to, it will use a canvas to own the pixels yet again. My bet, let Flutter mature out of beta for web and it is likely to be a better choice for web first development of SPAs (single page applications) than your favourite JS framework. It's a much better layout engine than the web's HTML/CSS paradigm and the runtime can be matured over time to improve performance. Even today, Flutter apps I've tested in the web are running better than there respective JS counterparts.

Thank you Flutter.

Post by Ryan