Setting up Flutter natively with WSL2, VS Code & Hot-Reload ๐Ÿ”ฅ

Since Microsoft integrated WSL (and especially WSL2) into Windows 10 – we, the developers – went crazy about it. It allows us to integrate our favorite Linux tools into our everydays development routines.

Working on web applications in PHP, NodeJS, etc… became a breeze.

Unfortunately, it wasn’t possible to integrate Flutter development into this breezy workflow – not until now! In this post, I’m going to show you exactly what to do, and I will explain some things along the lines why you need them, etc.

What we gonna do?

  • Install Java JDK, basically a one-liner
  • Install Android SDK, which at first looks crazy, but could also fit into one line ๐Ÿ˜›
  • Install Flutter SDK
  • Setup the necessary ENV variables
  • Connect a mobile device with ADB

Installation

We need to download some zip-files, extract them, put them into their locations and eventually reference their executables in the $PATH environment variable.

1. Java JDK

This one is pretty simple and self explaining.

sudo apt update && sudo apt install default-jdk
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin

2. Android SDK

Command line tools

These are crucial, since they come with the sdkmanager which we’ll use to install all the necessery tools and SDKs we need in the future.

mkdir -p ~/Android/Sdk/cmdline-tools
wget https://dl.google.com/android/repository/commandlinetools-linux-6858069_latest.zip -O latest.zip
unzip latest.zip
mkdir -p ~/Android/Sdk/cmdline-tools
mv cmdline-tools ~/Android/Sdk/cmdline-tools/latest
rm -rf latest.zip
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
sdkmanager

If everything went well, sdkmanager should output its version, which is, by the time of writing, 3.0

Plattform tools

Next thing we need, are the platform-tools which include adb. As you may’ve guessed, we’ll use adb later to connect our devices. We get these very simply via the sdkmanager.

sdkmanager --install "platform-tools"
export PATH=$PATH:$ANDROID_HOME/platform-tools
adb

If it’s successfull, adb should output something along these lines.

Android Debug Bridge version 1.0.41
Version 30.0.5-6877874
Installed as ~/Android/Sdk/platform-tools/adb

Build tools and Android images

As the last step of our Android setup, we grab the build-tools and images for Android 29, or whatever build you need. And finally we need to accept all the licenses for these.

sdkmanager --install "system-images;android-29;google_apis;x86" "platforms;android-29" "build-tools;29.0.3"
sdkmanager --licenses

3. Flutter SDK

Our final installation step is to grab the Flutter SDK.

wget https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_1.22.5-stable.tar.xz -O flutter_latest.tar.xz
tar xf flutter_latest.tar.xz
mkdir ~/Flutter
mv flutter ~/Flutter/Sdk
export FLUTTER_ROOT=$HOME/Flutter/Sdk
export PATH=$FLUTTER_ROOT/bin:$PATH
flutter --version

If everything went well, you should get Flutter’s version

Flutter 1.22.5 โ€ข channel stable โ€ข https://github.com/flutter/flutter.git
 Framework โ€ข revision 7891006299 (7 weeks ago) โ€ข 2020-12-10 11:54:40 -0800
 Engine โ€ข revision ae90085a84
 Tools โ€ข Dart 2.10.4

Let’s take a short break, shall we? โ˜•

… and see if everything works as expected.

By now you should’ve everything set up correctly. If you still face some errors during the setup, this is probably due to wrong ENV variables.

See, WSL2 inherits the ENV variables from Windows. So if you already have an ENV for flutter, sdkmanager, etc… set in Windows, your WSL2 distro won’t recognize the new paths. So, ensure that the tools point to the right destinations. If they do not, just adapt your export commands to append/prepend the paths.

which sdkmanager
which adb
# these should point to ~/Android/Sdk/...

which flutter
which dart
# these should point to ~/Flutter/Sdk/bin
Piece of delicious cheesecake on plate
Source: pexels.com

Now that we’ve had our coffee and cake, let’s get to the final and more interesting steps. Setting up VS Code.

VS Code

Open up VS Code with a new Remote WSL window. Once opened, install the Dart Code extensions for Flutter and Dart.

The Dart Code extension uses the FLUTTER_ROOT env to detect the flutter and dart binaries. So if everything went good in the installation process, there’s nothing to configure there.

Now, two things have happend. First, you should see a “No Device” message in the right part of the status bar. Which is a good sign ๐Ÿ‘ (for now)

No device

And when you hit Ctrl + Shift + P, you should see the Flutter commands.

Now, go ahead and create your first New Application Project so that we have something to test on in the next and final step, when we connect our first device.

Ctrl + Shift + P shows Flutter commands

Connecting your device

Finally we have everything ready, the only thing we need is a device to test our Flutter project on.

For now, unfortunately it’s not possible to simply plugin in your phone via USB and have it connected to WSL2, but fortunately adb allows us to debug over WiFi, and that’s what we’re going to do. For that, connect your phone via USB and open up PowerShell.

It’s a small step in Windows adb…

adb devices
adb tcpip 5555

# you may need to run adb-kill server and the two commands again

List of devices attached
 1234567       device

… but a big step in WSL2

Now go back to WSL2 and enter the following

adb connect <IP-of-your-phone>
connected to <IP-of-your-phone>:5555

adb devices
List of devices attached
<IP-of-your-phone>:5555       device

# you may need to run adb-kill server and the two commands again

To verify that flutter also has access to the device, run the following command.

flutter devices
1 connected device:
 ONEPLUS A6013 (mobile) โ€ข <IP-of-your-phone>:5555 โ€ข android-arm64 โ€ข Android 10 (API 29)

And, our good old “No-device-friend” VS Code should’ve recognized the device too.

VS Code working with Flutter โ™ฅ

You can now debug and write your Flutter applications under WSL2, use your favorite Linux toolkit for CI/CD and do whatever you please.

If you have further questions, let me know in the comments. I hope you enjoyed it.

  • Diego Carvalho says:

    Besides being able to compile for Linux Desktop, what are others advantages of using WSL for Flutter dev? Thanks

    • Str says:

      I’m not sure that there are any advantages at all. ๐Ÿคท๐Ÿผโ€โ™‚๏ธ

    • That’s a question everyone has to answer for themselves since the opinions tend to be more subjective.

      I personally prefer Linux over Windows when doing development work, and I’m sure that the majority does the same. That’s because you have tools on Linux which you can integrate into your CI/CD (continuous integration, delivery) pipelines allowing you to better organize your projects. Right now, my projects are scattered all over the place. PHP, NodeJS resides inside WSL, while Flutter is on the Windows side.

      Sure, you can omit all that and just create fancy and beautiful apps, with Flutter running on Windows, and be happy with it. Nothing wrong with that.

  • krelay says:

    Thank you for this!!
    have you found a way to connect an emulator to wsl adb?

    • Unfortunately, it appears that a Windows Update broke the Android Emulator running alongside Hyper-V enabled (which WSL2 relies on). So I couldn’t dig deeper into testing with emulators. As soon as everything works again, I’ll update the article.

  • WhereDartThou? says:

    I can’t get it to work. I’ve successfully installed Android and Flutter (flutter doctor only remarks missing android studio and devices). Setting the PATH through export seems to only work within wsl. which does print the correct path ofc, but trying to use these env variables on the Windows host doesn’t work.

    I guess they exist just for convenience as you can also set the path to the flutter install in the VSCode plugin. However, and here is my actual problem, if I set the path to the flutter installation directly (\wsl$homeuserFlutterSdk) VSCode recognizes the flutter install but isn’t able to load dart. As it turns out, the dart.exe is missing. There is only a dart.bat file. So I had to install the dart sdk on my Windows host… am I missing something or does it really not work anymore?

  • Bruce says:

    Thank you, great guide!

  • Anderson Antunes says:

    Greate!

  • Shashank Kapoor says:

    Hi there,

    Thank you for creating these instructions.
    All the installation went through OK on Ubuntu WSL, however, after the installation when I exit and open again. Flutter does not work. Gives me an error “flutter: command not found”.

    Could you please guide me on this please. Not sure why this is happening.

    Thanks in advance,

    Kind regards.
    Shashank

  • Hyoretsu says:

    Running WSL in VSCode remote, with all which’s pointing to ~/ and flutter devices recognizing my ADB connected through WiFi. However VSCode still shows no device, even though I have mobile, linux and chrome.

    • Hyoretsu says:

      Exported everything and prepended to path on ~/.zshrc

    • Hyoretsu says:

      Creating a project with VSCode’s flutter also doesn’t work, and I get “Dart DevTools exited with code 1. your 131072×1 screen size is bogus. expect trouble” every time. I have VcXsrv installed.

  • >