I’ve been following flutter on-and-off for the past year and a half. Although I primarily work on the backend, I tend to dabble with mobile apps from time to time. I was initially very skeptical about Flutter’s claims. I guess when you get a few gray hairs, you tend not to be excited about every new UI framework out there. Also, flutter sounds too much like flash or silverlight. In fact, Flare (a flash like studio) exports assets and dart code that can directly be used in a Flutter app.
Dart
One of the first things that you notice about flutter is Dart. If you’ve learnt Javascript / Typescript, then Dart is not very difficult to pick up. It feels very familiar and aside from a few syntactic differences you can feel right at home with Dart. Dart clearly shows its legacy as a Javascript compatible language in things like the syntax for Future
that is heavily inspired by promises and notable absence of numeric types beyond int
and double
. It also has an async
/ await
implementation that is identical to ES6 or its TypeScript counterpart.
Unlike Typescript, your values can be null
and there is no type safety around nulls. Dart also lacks some of the advanced type features such as intersection or union types. However, it does support Generics and a sort of a weird interpretation of interfaces and mixins. Until recently (before 2.1) mixins were simply abstract classes that you could mixin with
the with keyword. Dart now has a mixin
keyword.
There are a bunch of nice syntactic sugar around positional and named arguments for functions, cascade operator and factory constructors that make the language nice to work with. While Dart supports reflection, flutter does not support it as it relies on AOT compiler to generate efficient code for mobile devices. In addition to the AOT compiler, Dart also has a VM. Google intended for Dart to be a replacement for Javascript but it did not quite come to pass. Consequently, dart sports a JIT compiler. This makes for an awesome developer experience with Flutter with hot reloads.
UI framework
When it comes to cross-platform development, Flutter takes the approach of Xamarin. It takes a canvas and completely paints it. Flutter uses the Skia graphics library for all the 2d graphics. Skia is also used to drive the canvas implementation on Chrome both on desktop and on android. The library is quite performant. The flutter team has essentially re-implemented most Material Design components as flutter widgets and has commonly used iOS components as the cupertino library. It has an awesome animation framework and most of the common material and cupertino components implement the default suggested animations which can be overridden.
The flutter team has also taken care of accessibility of the standard components. As long as our components are composed of those standard components, we inherit the accessibility. However, if you are using something like Flare and using custom text and rendering, you are on your own to implement accessibility using the semantics widget.
The caveat with this approach is that it is not straightforward to include a native control to your flutter app. Unlike a framework like React Native where the UI components are all native Android or iOS views, flutter needs to make a hole in its canvas or mount it on top of the canvas. For the longest time, flutter apps did not have the ability to display google maps in line with other native controls the WebView until Flutter 1.0 thanks to the addition of AndroidView and UiKitView. Flutter provides native integration to the platform via MethodChannels. It's a bit like Erlang’s co-routines. You create a channel and both the native side (Kotlin/Swift) and Flutter (Dart) side can pass messages asynchronously to each other and act on it. AFAIK, there is no way to do synchronous calls. All calls to platform code is asynchronous.
State, Network and Persistence
Flutter natively supports react style setState
method to indicate the UI render loop to rebuild the component tree from that instance. However, as the app gets even slightly complicated, you would end up lifting the state up the UI hierarchy. There are various state management libraries like rxdart, flutter_redux and flutter_bloc. But my favorite ones are provider and get_it. The provider library works a bit like React’s context and lets you decouple state and let it be injected by consumers. With the provider library, you can write your entire application as a StatelessWidget
.
Since flutter does not support reflection, writing DTOs is a bit painful. However, there are code generation based solutions like json_serializable and built_value for generating DTOs. There are excellent Future and Stream based libraries like dio and web_socket_channel for HTTP and Web Socket based communications.
While flutter does not have support for an object database like Realm, it does support Firebase Storage (surprise). In addition to Firebase, Hive and Sqflite are two other databases that I know about. Hive is a fast but rudimentary and Sqflite is a wrapper around sqlite. Hive does support a generator that lets you almost use it like a Realm based object store. There are also ORMs like jaguar and sqfentity built on sqflite.
Non-UI concerns
There is more to mobile apps than just user interfaces. For example, you can launch background processes, set up geofences, provide location based services or background data sync. However, it is not very clear on how to do these with flutter except to drop down to the native layer. For example on Android, you’d need to understand native BroadcastReceivers, services, alarm managers, job schedulers and such and its equivalents on the iOS. Flutter has an awesome headless UI testing library. Once you have platform specific components, you’d have to test it on the emulator but as long as you keep it plain flutter its awesome fast.
Community
The flutter community is just awesome. People are really helpful and there is a ton of resources in terms of sample repositories, youtube channels and open source code. It is really easy to get started and there is frankly an explosion of open source widgets. I’d like give a special shout out to the Boring Flutter Show channel.
In Conclusion
I think flutter has turned a corner. Google along with the community has made a wonderful tool. It was a joy working with the flutter in terms developer experience. There is hot reload, excellent documentation and a helpful community to make me want to build apps with it. My only concern would be relying on Google to continue investing in it. They haven’t got the best track record when it comes to supporting moderately successful projects. As a mobile developer, flutter is a tool worth having in your tool chain. But be advised that it is not a substitute for your native platform but can be a very good accelerator. If you are interested in flutter, you should probably know that both the iOS and Android native ecosystem is also gravitating towards declarative UI like SwiftUI and Jetpack Compose. It is a very interesting time to build for mobile.