Getting Started with Flutter for Linux

Ubuntu

This post will not cover how to install Flutter on Linux, that can be easily done reading the following official guide. Instead, it will focus on building a Flutter app that runs on (Ubuntu) Linux.

Adding your Linux machine as a device

By default Flutter expects that you connect an Android or iOS device, or even a Chrome web browser to run the app. But in this case we would like to have a full-native Linux experience.

Flutter may report that you don’t have any connected device

$ flutter devices
No devices detected.

Run "flutter emulators" to list and start any available device emulators.

So in order to create and run a Flutter Linux app, not only the application must we created with Linux as a platform, but also we have to tell Flutter to enable Linux Desktop support.

$ flutter config --enable-linux-desktop
Setting "enable-linux-desktop" value to "true".

You may need to restart any open editors for them to read new settings.

If you are using a version of Flutter prior to 2.x, and upgrade is necessary at this point (flutter upgrade). Running Flutter doctor can tell us if there is something missing. A common situation in a fresh installed device may look like

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 2.0.0, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Chrome - develop for the web
[✗] Linux toolchain - develop for Linux desktop
    ✗ clang++ is required for Linux development.
      It is likely available from your distribution (e.g.: apt install clang), or can be downloaded from https://releases.llvm.org/
    ✗ CMake is required for Linux development.
      It is likely available from your distribution (e.g.: apt install cmake), or can be downloaded from https://cmake.org/download/
    ✗ ninja is required for Linux development.
      It is likely available from your distribution (e.g.: apt install ninja-build), or can be downloaded from https://github.com/ninja-build/ninja/releases
    ✗ GTK 3.0 development libraries are required for Linux development.
      They are likely available from your distribution (e.g.: apt install libgtk-3-dev)
    ✗ The blkid development library is required for Linux development.
      It is likely available from your distribution (e.g.: apt install libblkid-dev)
    ✗ The lzma development library is required for Linux development.
      It is likely available from your distribution (e.g.: apt install liblzma-dev)
[✓] Android Studio
[✓] IntelliJ IDEA Ultimate Edition (version 2020.3)
[✓] Connected device (2 available)

! Doctor found issues in 1 category.

Install all the necessary dependencies until Flutter doctor returns an output with all items checked, like this

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 2.0.0, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio
[✓] IntelliJ IDEA Ultimate Edition (version 2020.3)
[✓] Connected device (2 available)

• No issues found!

Now, with Flutter telling everything is okey, and the linux desktop support enabled, we can query which devices are enabled

$ flutter devices
2 connected devices:

Linux (desktop) • linux  • linux-x64      • Linux
Chrome (web)    • chrome • web-javascript • Google Chrome 88.0.4324.182

Creating the app

By default Flutter creates an app with several targets as default: iOS, Android, Windows, Linux, macOS and Web. In this brief tutorial, we will only create an app with Linux as the unique target.

$ flutter create --platforms=linux --template=app hello_linux

Flutter create can receive a list of platforms when creating an app, in this example only Linux will be created.

Using the template argument, we can create applications, modules, a Dart package, or a plugin (iOS and/or Android).

Running the application can be doing using flutter run command from the application’s directory. We can specify the target device, using the device-id argument as follows

$ flutter run -d linux

The output of the command above is especially important in order to archive an agile development. It contains not only the URL of the debugger, but also some shortcuts that let’s you use Hot Reload and Hot Restart on this native app.

$ flutter run -d linux
Launching lib/main.dart on Linux in debug mode...
Building Linux application...                                           

** (hello_linux:23299): WARNING **: 17:23:44.883: Failed to set up Flutter locales
Syncing files to device Linux...                                    62ms

Flutter run key commands.
r Hot reload.
R Hot restart.
h Repeat this help message.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
An Observatory debugger and profiler on Linux is available at: http://127.0.0.1:45697/9m8BapQhQeM=/

Flutter DevTools, a Flutter debugger and profiler, on Linux is available at: http://127.0.0.1:9102?uri=http%3A%2F%2F127.0.0.1%3A45697%2F9m8BapQhQeM%3D%2F

Development Environment

A recommend configuration for a Linux App Development is using Visual Studio Code with the Flutter plugin. On Ubuntu that can be installed using Snap.

$ snap install --classic code
$ code --install-extension dart-code.flutter

Bonus Track

Null Safety

When nullable safety is enabled types cannot be null be default. We have to explicitly say that they can be null.

The first benefit is that it prevents Null Pointer Exceptions (NPE) by throwing errors at compile-time instead of runtime. This is a huge improvement not only in stability but also in code quality.

For learning more about how Dart implements null safety, take a look at this post.

Null safety means that variables can’t contain null unless you say they can

Enabling null safety is done using dart migrate.

$ dart migrate --apply-changes