Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.flutter.dev
Flutter promises us that we are able to build an application that will run on Android, iOS, the web and the desktop. How much of this is true? How is it done? Does it allow us enough flexibility to create what we want, while still being able to run on all these platforms? Can we still use platform specific features and libraries? Are there alternatives to Flutter? Let’s find the answers to all these questions!
What is Flutter?
Flutter is a framework (SDK) in which you can create cross platform applications. Flutter includes a react-style framework, a 2D rendering engine, ready-made widgets, and development tools. The language in which you write your code is Dart. Notable features of the Dart platform are:
- Its support for “hot reload”, where modifications to source files can be injected into a running application. This allows for rapid development where you can directly see the results of your changes. You’ll see this demonstrated in this article as well.
- It is specifically designed for UI development
The base of a Flutter application is the Flutter engine. This engine interfaces with the underlying systems like Android, iOS, etc. Most of the engine is written in C++. It offers a number of core libraries for rendering, file and network I/O, a plugin system and a Dart runtime.
Another term you will see if you dive into Flutter is the “foundation library“. This is the API you will be talking to when writing a Flutter application. The foundation library is written in Dart and is the interface to all the underlying components offered by the Flutter engine.
Everything is a widget!
The base of Flutter consists of widgets. The flutter slogan is: “Everything is a widget”. A widget defines a part of the user interface. A widget can be anything: a button, a piece of text, a menu, a font or even the padding between elements. It may sound a bit unnatural, but once you see example code you’ll see that it actually makes sense. There are no separate files for layout and code. Everything that defines a widget is defined in one Flutter widget.
When the state of a widget changes, the widgets is automatically updated and redrawn if necessary. You don’t have to write code to watch state and update the UI.
As an example, if you want to center a piece of text you can simple do it by creating a Center widget and make the text a child of this center widget. It’s actually easy, perhaps even easier than working with an advanced constraints system like in Android.
To see which widgets are available in Flutter, check out the widgets documentation! Here you’ll see there are basically two sets of widgets. A set of material design widgets and a smaller subset of “Cupertino” widgets, which are strongly based on the current iOS design.
These widgets simply look good, and it is easy to combine them to create a stunning looking app. It is worth noting that these widgets do not rely on the underlying platform. They are part of Flutter and all Flutter needs is a canvas to draw them on.
To make this more concrete, I will demonstrate widgets with some example code:
body: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. child: Column( // Column is also a layout widget. It takes a list of children and // arranges them vertically. By default, it sizes itself to fit its // children horizontally, and tries to be as tall as its parent. mainAxisAlignment: MainAxisAlignment.center, children:
[ // Lets create a big fat mouse icon :) Icon( Icons.mouse, color: Colors.grey, size: 68.0, ), // And now a nice an clean divider (by default a horizontal line) Divider(), // .. our text: Text( 'You have pushed the button this many times:', ), // .. and some bigger text for our counter Text( // We use the $_counter variable (elsewhere in our code) to // display the number of click '$_counter', ), ], ), ),
In the next screenshot you can see the result of this code running in an Android emulator:
Besides widgets you can also directly manipulate the canvas through the foundation library. Most people won’t need this option as it is fairly low-level, but its nice to know the possibility is there. An example project that uses this is the Flame Engine, which is a game engine designed for Flutter.
Creating a mobile app (Android + iOS)
Let’s create a mobile app and see how easy (or hard) this is going to be. You can follow along and try this yourself, but feel free to just sit back and relax while I do all the hard work instead.
Installing Android Studio and Flutter
You can use any editor and any platform (MacOS, Linux, Windows) to create Flutter applications. Because Android Studio is supported, I highly suggest to use it since it is a great platform and it is completely free. Installing Android Studio is easy. Head over to the download page, follow the installation steps and you are done.
I’m using a mac, because that is what I have been working on primarily for the past 10 years. Lucky for me, this also allows me to test my Flutter app on iOS, since I have Xcode and iOS virtualisation installed already.
Next we need to install Flutter. This is perhaps a little bit more work, but still easy. Head over to ‘installing Flutter‘ and follow the steps. Make sure you also install the Flutter plugin for Android Studio. You can search for and install the plugin within the plugin preference dialogs of Android Studio.
Creating our first app
Now the fun stuff can begin. We start by creating a new Flutter project:
Next we choose to create a Flutter application:
Give our project a name (demo_app), a location on disk and a description. You may also need to point to the install location of the Flutter SDK. A nice extra when using Android Studio is that you can install the SDK from here too with the click of a button:
On the next screen, there are more options to fill in. Your company domain will define your package name. You can use anything here if you don’t have an actual domain yet. I used example.com. Next you have the option of using androidx.* artifacts. By using androidx you basically choose to use Android Jetpack. Jetpack is a suite of libraries, tools, and guidance to help developers write high-quality apps easier. If you create a new application, I would recommend using androidx, even though you shouldn’t have to worry about this at all if you only use Flutter and don’t do any of lower level native Android stuff.
You need to decide for yourself if you want to enable Kotlin and/or Swift support. Again, if you plan on staying within the Flutter SDK it doesn’t really matter what you choose here.
After clicking finish, you’ll have to wait while Android Studio does all kinds of project setup stuff. Once Android Studio is done, you end up with a very basic example app that you can run:
Since I run on MacOS, I have the ability to both create an Android emulator and an iOS emulator. The next screenshot proves that our demo app runs on both of these platforms:
As you might have noticed, there is a “DEBUG” label on the top right. The application performance won’t be great in debug mode, but it does allow us to do a couple of very neat things. Perhaps one of the biggest features of Flutter is its ability to perform a stateful hot reload. This means that you can change some code, hit save in the IDE and see the changes right away. The application won’t be restarted and even its state won’t be flushed. The relevant code is simply hot swapped. If it is code that defines a widget, that widget is redrawn right away. You can see a live demonstration of this in the following video I made:
Creating web applications
So can you actually create a web applications using Flutter? Well, I’m sure that one day we will be able to, seeing how much force and capacity is put into this project. But for now I couldn’t get even the simplest demo to run in a web browser. All I got was a blank page. I followed the instructions here. The SDK also warns about this feature being highly experimental as can be seen in the following screenshot I made in Android Studio:
Creating desktop applications
Finally, for creating native desktop applications I will have to disappoint you since this is hardy possible at the moment of writing. You can see the current status of desktop support on this Github page. Currently MacOS support is the most complete. Both Windows and Linux seem to be in the early stages of development. If you were hoping to create desktop apps using Flutter, I’m afraid that will still take a while to become stable and supported.
Having said that, I did try to run our demo app and with some extra code (you need to hardcode the target platform for now) I got it running on MacOS!
Using advanced or (native) platform features
One of the worries with an SDK like Flutter, is that you won’t be able to fully use the underlying platform. What if I want to add a background service in the future? Or want to read the battery status? Perhaps I need to access a device over USB later on?
To start off, yes you can run background code in Flutter. There’s a thorough article written on it here. It does require you to tap into the native platform so it is not trivial.
Secondly, yes you can read the battery status. There is actually a battery status plugin for it. But that defies the point I’m trying to make. You can write custom, platform specific code. In the example given in the documentation, they happen to show you how to read the battery level of the device. This obviously extends to other native platform features you may want to use, that are not supported by Flutter of one of the many plugins.
This shows us we are not limited to Flutter. There’s always a way to create platform specific code and link it to your Flutter application. So to answer that last question: you can access an external USB device this way. And yes, there are plugins for that.
Alternatives to Flutter
I have not tested any of the alternatives to Flutter. There are multiple alternatives that can be very interesting so I want to at least hand them to you for further research. Without judgement and in random order:
From Microsoft, we have Xamarin. It allows you to build cross platform apps in .NET.
Qt is another cross platform UI framework, which has been around for a long time. It is based on C++. and is used in many embedded devices, but can also be used to create desktop and mobile applications. Qt is licensed both commercially and open source.
Real life Flutter apps
Flutter is not just some toy project. There are companies using it for production grade apps. I could list them here, but you’ll be better off by checking out the showcase page on the Flutter website!
Downsides to Flutter
So far I’ve been very enthusiastic about Flutter. You might be wondering if there are any downsides to Flutter. Any negatives I could find? Of course there are. Most often, with newish projects like this, you only encounter the downsides once you really start using it. I’ve just started using it so I might find more on my way. In that case, I will update this post. If you found any problems yourself, please leave a comment to this post! I want you all to get a very clear and brutally honest view on Flutter, that includes naming any downsides.
No native audio
One very concrete problem I discovered was when I started to create a very simple app that could play a couple of audio tracks. Nothing fancy, just a list of mp3’s that you can click and then listen to. It turns out there is no native “Flutter way” or official plugin for playing audio. You have to rely on external packages from 3rd parties. But these plugins all have their problems, like working on just one platform, not working at all, not being up-to-date, still being very alpha/beta quality, etc.
In this regard, your best bet is to use the video_player plugin. It is developed by the Flutter team, can play all kinds of audio formats and works on both Android and iOS.
Next stop is playing audio when the app is closed. This requires another plugin, called audio_service. You need to combine this with one of the audio players to create an app that can play music even when you close the app. The good news is that it works, and that the audio_service plugin offers a working demo app to show you this.
I would expect this to be native parts of Flutter. If you want to be cross platform, you need to offer the basics. Playing audio is one of them in my opinion, just like playing video, using the camera, GPS and using the microphone. It would be nice to see the plugin ecosystem around Flutter become more mature and the core plugins officially supported.
A new language
I love the Flutter philosophy. It’s surprisingly easy to create an app in it. Its major advantage is obviously that it works on both iOS and Android! Knowing that web and desktop support are in the making adds to the excitement! Working with Flutter feels logical. It has a nice toolchain that does what it needs to do without making it complicated. The documentation is comprehensive. The fact that you can use Android Studio (which is basically a free IntelliJ IDEA) is a big, BIG plus too.
What I feared beforehand was that I would miss a visual design tool for the interface. But because of Flutters Stateful Hot Reload, it is incredibly easy to mock up an interface and directly see the results on a real device or emulator. All you need to do is save your work or press the hot reload button. It turn out you don’t need a visual design tool, you can just look at the results directly!
Building for the web is still in an early alpha phase. I couldn’t get it to work. Building native desktop apps is possible for MacOS, but like the web it is still highly experimental. Building for Windows or Linux is not possible at all for now. If that is what got you excited about Flutter, too bad but you’ll have to wait a bit more.
I do see a bright future for Flutter. Since you can develop for multiple platforms, Flutter will save lots of development time and thus money. Add to that the fact that Google seems to be putting serious effort into this project. Once Flutter has matured even more, there are not many reasons for NOT using it to create apps.
In a blog post called “A Production-Quality Flutter Starter App” by Greger Wedel, he researches how to build a production quality app in Flutter. He also created a Github repo with the results of his research.