tl;dr
WSLg is now available on both Windows 10 and Windows 11, making it the preferred mechanism for most users. See below for updated installation/update instructions.
(Much) more detail:
So the question asks for three "scoring" criteria for techniques for running Linux GUI apps in WSL:
- Ease of Installation
- Ease of Use
- Memory Consumption
I'm going to add to that:
"Easiest" is a matter of opinion, to some degree, but I'm happy to provide mine. In general, I think it's more important to understand all the available options and decide which one works for your needs.
At this point in time, there are at least three techniques for running Linux GUI apps under WSL:
- WSLg
- Install a third-party X server in Windows
- Install
xrdp
and a desktop manager in Ubuntu/WSL and connect via the Windows Remote Desktop Connection
I'll cover each below.
WSLg
While not an option when this question was originally asked, Linux GUI apps are now supported out-of-the-box on WSL2 using WSLg.
And when my answer was originally written, WSLg was only an option on Windows 11, making it unavailable to a large number of Windows 10 users who couldn't upgrade for various reasons. This has now changed with the release of the WSL application package, making installation much easier for most all users.
Windows 10 users currently require KB5020030 or later, meaning your Windows build number will end in .2311
or higher.
Windows 11 and Windows 10 xxxxx.2311
users should then be able to install or update with:
wsl --install
# or, if already installed
wsl --update
# to confirm:
wsl --version
GPU acceleration is also supported in WSLg using updated drivers. Pulse Audio is also preconfigured.
The WSLg architecture utilizes a read-only "system distribution" based on the CBL-Mariner distribution that Microsoft also uses for its Azure Cloud Services. This distribution is preconfigured to run Wayland/XWayland, with the sockets shared via the internal WSL network and symlinked to the appropriate files (e.g. /tmp/.X11-unix
) for each WSL2 distribution you install (e.g. Ubuntu).
The DISPLAY
and WAYLAND_DISPLAY
variables are preconfigured by the WSL /init
(PID 1) process on initial startup.
Note that WSLg only works for WSL2, not WSL1 instances.
WSLg Summary and Scoring:
Ease of install: Now that Windows 10 users can also install, this is almost certainly the easiest of the three techniques for most use-cases.
Ease of use: Excellent
Flexibility: Most flexible in some ways -- Runs Wayland/Weston/Xwayland. Can run a Weston-on-Weston implementation to run a full screen desktop if desired.
Memory Consumption: Short answer -- Around 213MB to run xterm
. We can assume the majority of that is from the WSLg infrastructure. Regardless, I also tested the other two scenarios below with xterm
, so it's memory usage is the rough constant in these measurements.
See footnote at end of this post for more information on the memory usage of WSLg. Note that this includes Wayland, Xwayland, and Pulse Audio support with this memory footprint. The other two options listed below do not include Wayland or Pulse Audio.
Performance: Highest once it is loaded - GPU accelerated. glmark2 of 666 on my system (nVidia 2070 Super), which sounds low, but remember that this is being composited onto the Windows desktop. It's almost double that of VcXsrv and around 4 times that of xrdp.
However, note that there is an initial delay while the system distribution is copied and started the first time you launch any GUI application in a WSL2 session. On my, high-midrange performance system, this delay is about 5 seconds. Additional GUI application launches after that are sub-second.
xrdp
For those who cannot upgrade to Windows 11, or for those who still need WSL1 support, there are still two good options. The first, and my preferred method, is to run xrdp
in Ubuntu and simply use Microsoft's Remote Desktop Connection with something lightweight such as Xfce4.
sudo apt install xrdp xfce4
sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak
sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini
# So it doesn't interfere with Windows RDP on 3389
In /etc/xrdp/startwm.sh, comment out the last two lines (that mention Xsession) and add:
#test -x /etc/X11/Xsession && exec /etc/X11/Xsession
#exec /bin/sh /etc/X11/Xsession
exec startxfce4
Start xrdp with:
sudo service xrdp start
And that's it -- You should be able to connect to your WSL Desktop using the built-in Remote Desktop Connection app. The computer to connect to will be localhost:3390
. Make sure Xorg is selected as the Session type.
With this method (as with WSLg) there is no need to configure any firewall rules, since you really are using WSL's built-in localhost forwarding, which routes localhost
traffic to WSL when there isn't a listening socket on that port in Windows.
I personally find this far easier than the other answers here regarding third-party X servers. It is probably not, however, the most memory efficient since it requires running a desktop environment.
xrdp Summary and Scoring:
Ease of installation: Excellent as long as the desktop manager does not require Systemd (e.g. Gnome). Getting Systemd to run in WSL is currently a major challenge. Third-party helpers are available, but the system and usage of WSL change drastically under Systemd.
Ease of use: Pretty good - Isn't automatically configured to startup when needed, so it's not quite as seamless as WSLg. Some people have reported that it is not as performant as VcXsrv, but I've also experienced excellent performance.
Flexibility: Least flexible for windowing options. You must run a window manager, at least, and configure it for xrdp. It cannot run single-applications on the Windows desktop. Both WSLg and third-party X Servers can run either full-screen or windowed.
This method does run under Windows 10 and should run under WSL1 as well, although I can't remember if I've actually tested xrdp with WSL1.
Memory Consumption: As I expected, this technique has by far the highest memory consumption. Starting the Xfce4 desktop under xrdp consumed an additional 687MB under Vmmem.
Performance: My personal use of xrdp has been limited to simple UI apps, and performance has been pretty responsive. However, deeper inspection shows that this is certainly the worst option for performance. H.264 video playback using VLC stutters heavily, and the glmark2 score of 167 is about half that of VcXsrv.
Third-party X Server in Windows such as VcXsrv
Finally, the "normal" recommended method (as mostly mentioned in the other answers here) for Windows 10 and/or WSL1 is to install a third-party X server in Windows and configure Ubuntu in WSL (version 1 or 2) to use it.
I will add that the older methods of setting the DISPLAY
variable for WSl2 are probably a bit out of date. I recommend using:
export DISPLAY="$(hostname).local:0"
This utilizes mDNS (the .local
domain) which has been available in Windows 10 and WSL for a few years now. Since your hostname
in WSL Ubuntu is the same as your Windows "computer name", this automatically connects to the correct IP address of the Windows host.
For WSL2, a firewall rule will need to be in place for this option, since you are connecting "across network" (albeit a virtual network). In my experience, Windows will detect the attempt to connect the first time and request user action to automatically create a firewall rule. However, if this message is missed or dismissed, the rule will have to be configured manually.
For WSL1, no firewall rule is necessary, and the "normal" DISPLAY=:0
should work, since it shares the same network interface as Windows (where the X Server is running).
Getting a third-party X Server set up is certainly not the "easiest", so I recommend reading through the other answers here (and elsewhere), if you run into trouble with that technique.
One additional note regarding the firewall rules -- The WSL2 network under Windows is classified as a "Public" network interface, and there doesn't seem to be an easy way to change this in recent Windows releases. It used to be possible, but now that interface is hidden and can't be changed. This means that you have to set up your firewall rules to allow VcXsrv (or any third-party X server) on public networks. This can be a problem if you connect to other untrusted, Public networks.
Remember to either:
- Shut down VcXsrv when connecting to untrusted networks
- And/or enforce access control in the X Server.
Third-party X Server - Summary and Scoring:
Ease of Installation: Most trouble-prone of the three options, IMHO. Your results may vary, but as you can see from the number of answers (and questions posted across the Stack sites), people do tend to run into various issues with this technique. Cross-network communication (from the Windows host to the WSL2 virtual network) complicates matters.
Ease of Use: Moderate to Easy once installed and configured properly. While WSLg will start "on demand" when the first GUI app is executed in WSL, you do need to start the third-party X server yourself when you need it. Or you could leave it up and running at all times, but this will mean longer-term memory use.
Flexibility: High - Can run either windowed or full-screen. No Wayland option currently.
Runs on Windows 10/11 and WSL1/WSL2.
Memory Consumption: The best case of these three options. Consumed only 48MB total -- 10MB increase in Vmmem and another 38.6MB for VcXsrv itself.
Performance: While I've tended to prefer xrdp, my benchmarking today will have me taking a closer look at VcXsrv in the future (and perhaps other X servers, such as MobaXterm). VcXsrv does some OpenGL acceleration, apparently, and its glmark2 score of 322 was just about double that of xrdp's. VLC playback of H.264 was smooth, even at 3440x1440 (sorry, no 4k with which to test).
Footnote: Measuring memory
To determine the rough memory usage of each technique, I looked at the Vmmem process memory consumption in Windows. This is the virtual machine process that handles WSL2. I rebooted Windows between most of these tests as well, but did a wsl --shutdown
between tests of the same technique.
Note that it is possible to enable PulseAudio with each of these options, but only WSLg includes it pre-configured out-of-the-box. I did not enable PulseAudio support on either xrdp or VcXsrv options, so whatever memory is needed there (if you need audio support) is not taken into account.
Footnote: WSLg memory consumption
There are apparently two "bumps" in memory consumption with WSLg. The first occurs when you start WSL2 with WSLg simply "enabled" (the default). I didn't notice this increase at first, because I've never disabled WSLg. It is entirely possible to turn the feature off entirely by editing the .wslconfig
file (see this doc) and setting guiApplications=false
in the [wsl2]
section.
After disabling that feature and restarting my Ubuntu WSL2 instance, my base memory usage dropped 108MB. Turning it back on and restarting showed an increase in "steady state" WSL2 memory consumption. So there's a small penalty to having this enabled all the time.
Then when starting up the initial x client (xterm
in this case), there's another 105MB bump in Vmmem.
Footnote: Optimizations
In general, I ran each of these methods using the out-of-the-box, default configuration. I did enable OpenGL acceleration in VcXsrv, and my Windows nVidia drivers are the latest and confirmed to be used for OpenGL Mesa in Ubuntu.
There may be additional optimizations possible for each technique that would improve performance.