Flutter — make cross-platform development great (again)

Stefan Blos
8 min readApr 27, 2018

--

What is Flutter?

Flutter is the new, hip cross-plattform, open-source, mobile development framework made by Google. What does that mean? It means one codebase to rule them all. No need to dig into Swift/Objective-C to build an iOS app and rebuild the whole thing with Kotlin/Java.

Of course Google wasn’t the genius to come up first with this idea. There are multiple other such frameworks like Xamarin, Nativescript and React Native amongst many others.

So why create another framework? Well one theory is that Google just wants to jump on the bandwagon and hacked up something quick to build just another framework. That’s wrong. It was definitely not a quick shot but a well thought out creation. Why? I’m glad you asked…

(Disclaimer: there won’t be much sample code in this post since this is meant to be an introduction to the framework and how it works. Code samples are for future posts)

What does Flutter do differently?

1. Dart (not the sport)

First of all there is the language. Flutter code is written in Dart. Not only the application code but also (most of) the whole framework. Since it is open-source you can see all the code on GitHub. Most other frameworks use a web-stack (some combination of JavaScript, Typescript, HTML, CSS and the like) so why did Google choose Dart? This choice seems even more strange after they announced Kotlin as the new Java-alternative for Android development.

If you have never heard of Dart don’t worry it is mainly used inside of Google and even developed by them. Here you have your first advantage: A language which is directly maintained by the creators of the framework can be very tightly coupled and optimized towards performance. The “others” are mostly relying on more general purpose languages like JavaScript which is not necessarily a bad thing. But since it is used for so many different things it has to serve many purposes making optimization on a specific use-case difficult.

So if you now think there is still a lot of effort required to learn Dart I want to present you with a (probably unofficial) quote by a Dart team member:

I wish it had a little more razzle-dazzle but I can’t deny that literally on my first day of writing Dart code, I was productive in it.

I agree with that. If you have learned some JVM language like Java or JavaScript you will feel very familiar with Dart. It does not have much fancy functionality. There is some useful functionality such as one-line functions but other than that it is just robust:

This code will look very familiar even if you have never seen Dart.

This is even enhanced by the fact that starting with Dart 2 type safety is introduced. Flutter makes use of a reactive programming style (which is also used in React Native). While this is not a new idea it performs exceptionally well with Dart. That is because it uses a garbage collection which is great for allocating (and releasing) many short-lived objects. Also it has features like yield, Futures, async/await and Streams that are great for this programming style.

Dart is super easy to learn and really intuitive to use and comes with great properties making it a great choice for the reactive programming style of Flutter.

2. Hot Reload

If you are coming from native development you are probably used to the following workflow:

1. Do minor code changes
2. Wait forever until your app is built
3. Forget what you changed and start with 1.

Well with Flutter this will change. With hot reload you change something in any file, hit the save button AND IT’S THERE. It really is that easy. While Android Studio is trying to reach this with Instant Run there is still a difference. This is because one of the best things about hot reload is that the state of your app is preserved. You already entered text into a TextField? It’s still there! Look at this example where the amount of taps is preserved even after making changes to the text and the button:

Taken directly from https://flutter.io/

To all of you who have not fainted yet and haven’t fallen off their seats in amazement this can actually change the development process a whole lot. If you can so quickly change something and see the results the development process becomes much more iterate-ish. I couldn’t believe this at first but it really had quite an effect on me.

This also makes debugging a whole lot easier. Since the Dart VM and its state can be debugged without using a specific IDE this means freedom of choice. In fact there are multiple supported IDEs for Flutter including Android Studio / IntelliJ IDEA or even Visual Studio Code (which has been my choice so far and been a delight to work with). So it’s safe to say that tooling is also great!

Another great thing is that this scales extremely well. If you have listened to the excellent Fragmented podcast episode (if not I highly recommend to do that — and also part 2). Eugenio Marletti — one of eight Google Developer Experts (GDE) for Flutter worldwide — explains this beautifully. It means that only the code you change is pushed and hot reloaded making it very efficient.

Hot reload combined with the great tooling support allows for extremely fast development cycles and awesome debugging

3. Everything is a widget — and they look beautiful

One of the most important lessons you need to learn in Flutter is that everything is a widget. Yes, EVERYTHING! You want to display text on screen? There’s a widget for that (Text). You want to input text? There’s a widget for that (TextField). So far so good, this is what most of you will probably know from mobile or the web. But what about centering something on the screen? By now you might have gotten the hang of it — there’s a widget for that (Center). This might sound really weird at first because it is quite different than how it is done in other frameworks. But once you’ve gotten the hang of it it becomes pretty intuitive to build your screens completely through widgets. To build a widget with centered text this is the complete code:

This is all the code needed to create this widget.

Another thing that helps with that is that your layout is actually defined in code. Depending on where your expertise lies you might be used to .xml-files (Android), Storyboards (iOS) or a combination of HTML and CSS (web). This changes with Flutter — you have everything in one place. This is actually great combined with the hot reload feature since it makes your development flow insanely fast. You don’t need to switch between multiple files and then build a project. You build your layout widget by widget and can check at any by simply saving the file and seeing the results directly appear in the app.

As you might think one problem there is that you have to pay attention that your layout code will not get too messy. Flutter lives by the principle of composition over inheritance. This means it is favored to not create new widgets that inherit from others but instead combine the existing widgets to form new ones. By doing that you can simplify your layout by extracting complex widget combinations into multiple parts and just putting them together. By doing that you guarantee a better structure as well as greater readability of your code.

Every layout component is a widget, making it intuitive to build up your layouts step-by-step and having one single place in code where everything is defined

4. Performance is great

One major concern of cross-platform frameworks has always been performance. Older frameworks like Ionic or Cordova make heavy use of WebViews. The general procedure here is that the JavaScript code that is written displays its content in the WebView of the mobile platform. Of course this limits the abilities of the app and in addition to that there is also a JavaScript Bridge that is talking to the system services like location, camera, etc. One can imagine that communication through this bridge and then back to the JavaScript code and then on to the WebView has certain performance indications and an overall limitation.

What React Native does is that it does not use the WebView to render content inside of your mobile app. It keeps the JavaScript bridge to manage all the communication between your JavaScript code and the respective platform. But it uses that to access the native components used on the system. This means that if you want to display text on screen it will go through the bridge and then create a UILabel (iOS) or a TextView (Android). This gives the apps a more natural look-and-feel since it re-uses the components that are well-known to the users. However, the JavaScript bridge remains and still has to manage the layout as well as the communication with the system services.

Flutter goes a different way. As mentioned before they use Dart as a language. The dart code is actually pre-compiled ahead of time (AOT) into native code. It then uses different layers to build up your UI. The lowest layer — which you probably won’t want to access — actually creates a canvas and draws your whole layout onto the canvas. This means that it does not use the system components like the aforementioned UILabels or TextViews. It really draws your created Widgets onto the screen. This means that you can use the look-and-feel of native apps (they have MaterialWidgets for Android and CupertinoWidgets for iOS) without having the need for a JavaScript bridge. This eliminates the potential bottleneck of such a bridge and increases performance.

Aside from those great compiler options Flutter has mechanisms that allow for object allocation and garbage collection without locks. It also does not use preemptive scheduling and shared memory making it easier to eliminate concurrency bugs. All those things leads to their promise to constantly aim for >60fps. With that animations and scrolling is buttery smooth in production mode. An excellent article with a lot more details on why Dart is great for use in mobile and even on the web can be found here (it is really awesome).

Compiler options of Flutter allow for great development support (JIT) with optimal debugging properties and for really fast and native (AOT) performance in production environments.

Wow Flutter really is great!

So if you continued to read up to this point I hope I was able to show you why Flutter is actually pretty cool. It combines a lot of things from different other approaches and tries to optimize the way you can use one codebase to rule them all. There is a lot of things that I even didn’t mention to keep the length of this post readable, like:

  • great community support (there is even a gitter where you can chat directly with the Flutter folks and they are really active there)
  • beautiful UI right out of the box (see their examples)
  • easy to integrate native code if you need to
  • great testing support

I wrote this post as a starting point and want to dive deeper into both the creation of Flutter apps as well as deeper explanations on how Flutter works internally. So if you enjoyed reading this please let me know what you would like to be covered in future posts. You can do this either in the comments here or via Twitter @stefanjblos.
(Also huge thank you to the people who gave feedback on this post, especially Marco and Nino)

--

--