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.
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.
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.
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.