visit
Before I start, in case you haven’t heard about it, is an app SDK (backed by Google) to build ‘modern mobile apps’. It is still in alpha, but comes with great documentation and tooling, with some production apps already out.
I am a hobbyist developer, and I recently launched an app using Flutter myself. It was such a pleasurable experience, that I had to share why I liked it so much.
My goal is to try and convince native app developers (iOS/Swift/ObjC or Android/Java/Kotlin) to give Flutter a serious look. The fact that the same code can run on Android and iOS is arguably not the biggest reason why Flutter will impress you the most. Without further ado, here are the reasons why I feel Flutter is what the future of app development will look like. Listen up yo!
So in Dart’s defence, it is a simple language to learn, and is unlikely to be a deterrent for trying Flutter out. Have a look at this sample class in Dart.
class Vehicle {final int numberOfWheels;final double mileage;final double horsePower;
int speed = 0;Vehicle(this.numberOfWheels, this.mileage, this.horsePower);
void accelerate() {speed = speed + 1;}
void decelerate() {speed = speed - 1;}
void brake() {speed = 0;}}
As you can see, it is pretty straightforward to read with syntax similar to most popular object oriented languages. Of course, there is some language specific syntactical sugar, and you can start writing code that is more concise once you learn the language, but my point is that the learning curve is rather small. In fact, if you have not tried Swift/Kotlin, then Dart might be a good alternative to play around with.In Flutter’s defence: Google/Flutter had . The way Flutter works, it needs to create and destroy a large number of short lived objects very fast. Dart’s ‘garbage collection’ is very well suited for such a use case. And it shows in the performance of the apps that can be built using Flutter.
So assuming that you’ll not be writing off Flutter just because of Dart, let me proceed further.Layout XML’s / JSX (React native) In Flutter, layouts are defined using Dart code only. There is no XML / templating language. There’s no visual designer/storyboarding tool either. My hunch is, upon hearing this, a number of you might even cringe a little. Prima facie, that was my reaction too. Isn’t it easier to do layouts using a visual tool. Wouldn’t writing all kinds of constraint logic in code make things overly complicated?
The answer for me turned out to be no. And boy! what an eye opener it has been. Let me try and make that case.
First of all.. meet Mr. Hot Reload.
Here is a sample with app code and the emulator side by side. This is a totally custom layout with a top and bottom bar and a middle container for the content. The code you see is the _whole_ code needed to run the app.
There is no separate layout xml, no xib file etc. The changes you make in code can be hot reloaded instantly. Hot reloads even preserve your application state, so you don’t even have to click and reach the screen you were on to proceed. I can’t stress enough how this is light years ahead of Android’s Instant Run, or any similar solution. It just works, even on large non-trivial apps. And it is crazy fast. That’s the power of Dart for you.
In practice, that makes a visual editor interface redundant. I did not miss XCode’s rather nice auto layout at all.
And as a result, I have been way more productive writing layouts in Flutter (Dart) than either Android/XCode. Once you get the hang of it (for me that meant a couple of weeks), there is a substantial overhead reduction because of very little context switching that is happening. One does not have to switch to a design mode, and pick a mouse and start clicking around. And then wondering if something has to be done programmatically, how to achieve that etc. Everything is programmatic. And the APIs are very well designed. It becomes intuitive soon and is much more powerful than the constructs offered by auto layout / layout XMLs.Lets imagine how you would go about architecting such an app in native Android (or iOS). Since this is a simple one page app, lets just say we’ll code it all in a single Activity (or ViewController). In an imperative style, the structure would look something like this…
Imperative style of code
How it works: There will be a listener to track changes in the TextField and the Dropdown values. On change we would be obtaining an instance of the Text label and calling the relevant methods to update its values. (It is likely that we will be keeping these values in some private instance variables to maintain state as well)
This means, that in a typical public API for a View in Android or iOS, you would find a number of getters and setters for various properties. For example, look at the public API for the TextView class in Android. I can’t reproduce it in full here as it is too long. The number of methods it has is in the hundreds — 259 to be exact, plus 4 constructors. Some methods in the Android TextView.java class
Reactive style of code
How it works: There will be a listener to track changes in the TextField and the Dropdown values. On change we would be updating these values in the ‘global state’ and tell Flutter to repaint.
Flutter will automatically take care of figuring out what the Text label should look like. This style of coding comes with a lot of advantages. For example, suppose the next version of this app has another greeting text widget added to it, that says “Bye”.Now in the imperative style, the listeners will need to be updated to call the relevant setter methods on the new “Bye” text widget (or View) as well. Whereas, in the reactive app, the listeners stay the same. They will continue to update the global state (as earlier). The new widget will simply repaint itself as per that state. In complex apps, this style of coding really starts to shine. It is much simpler to maintain and reason about. Another advantage is that the public API is hugely simplified. Although this is also due to the Widget architecture of Flutter (which is explained in the next point). To illustrate, have a look at the code for the Text widget in Flutter. class Text extends StatelessWidget {Hello <name>. Bye <name>.
It has a single constructor. And that’s about it. The other two methods are to be called by the framework. This is the whole code with the comments removed and a few lines removed from the overridden methods. Isn’t it elegant? It is possible in part because there are no setters and getters. The Widgets prefer to rebuild themselves using their constructor arguments, rather than mutating themselves using setters.
Reactive vs imperative, the mindset change:
I feel if you’ve always been coding in an imperative style, the appreciation for a reactive style comes once you actually try it out and it _clicks_💡. In the beginning, I spent a lot of time trying to figure out how I’ll call a method on a child widget to update its internal state (like the greeting label in our example). I was stuck in an imperative mindset of doing things. I remember what lit a bulb in my head after struggling for a few days. It was a conversation I was having with a friendly member on the . Here was his advice (emphasis is mine).
@rrousselGitA widget shouldn't visit it's children. It becomes messy. But you can access the state of your parents.
@rrousselGitThink in immutable. Don't update the child. Update the parent, and create a new batch of child. Once you get used to it, you realize it has a lot of advantages.
The architecture in Reactive tends to be more around figuring out how to manage State. This deserves proper discussion in a separate series of articles, as there are multiple ways to doing it. But needless to say, once I got the hang of this style of coding, it was pretty awesome. Just speaking from the experience of having built a fully functional app now, I realise I have spent almost zero time on bugs caused by side effects!What is a widget?
For most developers, a widget typically invokes a mental picture of an element that renders on a screen and encapsulates some behaviour. The Android and iOS counterparts would be the various View classes. Flutter has taken a different/broader view of this concept, and in the process has extended it beyond just structural elements. The widget architecture heavily favours composition over inheritance, thus making widgets much more powerful and composable (duh!). Quoting from -Even a behaviour is a widget (like ). There is a type of widget that helps with state management (), and one that helps build animations (). Quoting again from the documentation-
A widget can define- a structural element (like a button or menu)- a stylistic element (like a font or color scheme)- an aspect of layout (like padding)and so on…
By following “Composition > Inheritance”, the widgets start from primitive ones, to some really complex ones. For eg. the provided by Flutter is composed of a number of primitivesYou can also control the layout of a widget by composing it with other widgets. For example, to center a widget, you wrap it in a Center widget. There are widgets for padding, alignment, row, columns, and grids. These layout widgets do not have a visual representation of their own. Instead, their sole purpose is to control some aspect of another widget’s layout. To understand why a widget renders in a certain way, it’s often helpful to inspect the neighboring widgets.
Container is made of upto 7 nested widgets! The ingenuity of this design strikes once you start building. The framework make it extremely easy to customise the look and feel of any stock widgets, and build your own if needed. And this has the effect of making the API footprint very small. For eg. every Text widget does not need a property called Padding. You simply wrap the Text widget with a Padding widget. To repeat, they key thing to remember is… Composition over Inheritance. It is powerfully applied throughout Flutter’s API and makes it really elegant and simple.
This article by (developer advocate @ Google) does a great job of explaining why Flutter’s rendering is crazy fast - //gzht888.com/whats-revolutionary-about-flutter-946915b09514. I’ll just borrow from this article and post a few diagrams and quotes that present a TLDR version of it, comparing the three architectures - Native vs React Native vs Flutter.
Native apps (Java/Swift)
How native Android/iOS code interacts with the platform
Your app talks to the platform to create widgets, or access services like the camera. The widgets are rendered to a screen canvas, and events are passed back to the widgets. This is a simple architecture, but you pretty much have to create separate apps for each platform because the widgets are different, not to mention the native languages.
React Native apps (Javascript)
How React Native interacts with the platform
React Native is very popular (and deserves to be), but because the JavaScript realm accesses the OEM widgets in the native realm, it has to for those as well. Widgets are typically accessed quite frequently (up to 60 times a second during animations, transitions, or when the user “swipes” something on the screen with their finger) so this can cause performance problems. As puts it:
Here lies one of the main keys to understanding React Native performance. Each realm by itself is blazingly fast. The performance bottleneck often occurs when we move from one realm to the other. In order to architect performant React Native apps, we must keep passes over the bridge to a minimum.
Flutter apps (Dart)
How Flutter interacts with the platform
Flutter takes a different approach to avoiding performance problems caused by the need for a JavaScript bridge by using a compiled programming language, namely . Dart is compiled “ahead of time” (AOT) into native code for multiple platforms. This allows Flutter to communicate with the platform without going through a JavaScript bridge that does a context switch.
Flutter has a new architecture that includes widgets that look and feel good, are fast, and are customizable and extensible. That’s right, Flutter does not use the OEM widgets (or DOM WebViews), it provides its own widgets.
Flutter moves the widgets and the renderer from the platform into the app, which allows them to be customizable and extensible. All that Flutter requires of the platform is a canvas in which to render the widgets so they can appear on the device screen, and access to events (touches, timers, etc.) and services (location, camera, etc.).Do give that article a full read in case you want to understand Flutter’s performance better. If you’re on Android, you can try the Flutter gallery app, it has some very cool animations showcased - . Here’s a gif from that app
(iOS app store does not list demo apps, so on iOS you’ll have to build it for yourself - ) This brings us to our penultimate, but one of the biggest wins of Flutter…
And last but not the least is…
This is a very important point because Flutter is new (and alpha). And from that perspective, the community support is very good. The has constant chatter and a good mix of newbies and experienced devs hanging out. Most of my questions got answered within a few hours there. For longer form questions, is also answered pretty fast.
The Flutter dev team that hangs out on chat is very helpful. They’re very welcoming of new people and answering the simple questions that we tend to get stuck at. And in general I found the tone of the conversation to be humble and authentic. I think it bodes well for the future of the framework. That’s all folks. I hope I’ve been able to convince you to play around with Flutter. The article is mostly talking about the positive aspects of Flutter, because in my development experience that is what my overwhelming experience was. That doesn’t mean there are no shortcomings.The caveat is that Flutter is new, so there are known issues/limitations, and of course unknown ones that may come along. It is not within the scope of this article to address the limitations. Also, many limitations are a moving target and the Flutter dev team is closing stuff rapidly.
Listing some of the limitations here, that seem to be commonly brought up in the community -If you enjoyed this article, please share within your network. And if you play poker, try giving (the app I made using Flutter) a spin.
Thanks!