Response to “Flatpak Is Not the Future”
Table of Contents
Introduction§
Late last year, this interesting article “Flatpak Is Not the Future” was published to the public, and very quickly grabbed the Linux community’s attention. I want to go over some of the author’s arguments and explain some of the misunderstanding and claims.
Do keep in mind that I have nothing against the author’s opinion. The point of this response is to reduce the amount of misinformation and misunderstanding that the article might have caused, as I have seen (and still see) many users post this article very frequently, without having a proper understanding of the subject.
“Size”§
Suppose you want to make a simple calculator app. How big should the download be?
[…]
Other solutions like Flatpak or Steam download the runtime separately. Your app metadata specifies what runtime it wants to use and a service downloads it and runs your app against it.
So how big are these runtimes? On a fresh machine, install KCalc from Flathub. You’re looking at a nearly 900 MB download to get your first runtime. For a calculator.
ID Branch Op Remote Download 1. org.freedesktop.Platform.GL.default 20.08 i flathub < 106.4 MB 2. org.freedesktop.Platform.VAAPI.Intel 20.08 i flathub < 11.6 MB 3. org.freedesktop.Platform.openh264 2.0 i flathub < 1.5 MB 4. org.kde.KStyle.Adwaita 5.15 i flathub < 6.6 MB 5. org.kde.Platform.Locale 5.15 i flathub < 341.4 MB (partial) 6. org.kde.Platform 5.15 i flathub < 370.1 MB 7. org.kde.kcalc.Locale stable i flathub < 423.1 kB (partial) 8. org.kde.kcalc stable i flathub < 4.4 MB
Note that the app package itself is only 4.4 MB. The rest is all redundant libraries that are already on my system. I just ran the
kcalc
binary straight out of its Flatpak install path unsandboxed and let it use my native libraries. It ran just fine, because all of the libraries it uses are backwards compatible.Flatpak wants to download 3D drivers, patented video codecs, themes, locales, Qt 5, KDE 5, GTK 3, ICU, LLVM, ffmpeg, Python, and everything else in
org.kde.Platform
, all to run a calculator. Because unlike AppImage, the runtime isn’t stripped down to just what the app needs. It’s got every dependency for any app. It’s an entire general-purpose OS on top of your existing OS.
Flatpak installs these runtimes to ensure that you and other users are running the exact same binaries and libraries across different systems, whether the libraries are backwards compatible or not. This is done to reduce the amount of quality assurance (QA) needed by app developers and to reduce bugs as much as possible, so they can test builds that were tested against the same toolchain and dependencies.
By running host libraries, there is a risk of running into distribution specific bugs, or from other sorts of negative side effects due to, e.g. patched libraries, slightly older or newer versions of libraries, overlooked dependencies, etc.
Also, this is actually quite similar to system packages. Suppose you are using GNOME on your system, and you decide to install KCalc. If you don’t have Plasma dependencies installed, then the package manager will download and install all the needed dependencies, which should install the 4.4 MB for KCalc atop the Qt and Plasma dependencies.
The more apps you install, the more space efficient Flatpak becomes. Flatpak goes through a process called deduplication, where it reuses dependencies whenever possible, avoiding the need of duplicating data. In the author’s example, KCalc pulls 900 MB because of the runtime and drivers. Now, suppose you install 10 more Qt apps. Instead of redownloading and reinstalling 9 GB (900 MB of runtimes × 10 times the Qt apps), it will not redownload and reinstall 10 times, and you will not have wasted 9 GB either. Instead, all 10 Qt apps will keep using the same 900 MB that come from the runtime. Deduplication ensures that apps that rely on the same dependencies will keep reusing them. Basically, the more apps you install, the more space efficient Flatpak becomes.
In the author’s example, it’s worth noting that, next to org.kde.Platform.Locale
and org.kde.kcalc.Locale
, it mentions “(partial)”, meaning only parts of them are downloaded. On my end, this is what happens when I install KCalc:
ID Branch Op Remote Download
[...]
2. ✓ org.kde.Platform.Locale 5.15-21.08 i flathub 17.8 kB / 345.4 MB
7. ✓ org.kde.kcalc.Locale stable i flathub 5.6 kB / 431.5 kB
[...]
org.kde.Platform.Locale
takes around 0.005% of 345.4 MB, and org.kde.kcalc.Locale
takes around 1.30% of 431.5 kB. If we calculate the results instead, it takes around 555 MB out of 900 MB, which is roughly 62%.
“Sharing Runtimes?”§
They claim that they deduplicate runtimes. I question how much can really be shared between different branches when everything is recompiled. How much has
/usr
changed between releases of Ubuntu? I would guess just about all of it.
Regarding this section, Will Thompson already wrote a response on his website “On Flatpak disk usage and deduplication”. He looks over the sizes of runtimes and how much deduplication takes effect. It’s a very detailed explanation on deduplication, and I recommend reading it.
To summarize, between the freedesktop.org 20.08 and 21.08 runtimes, 113 MB out of 498 MB were deduplicated. And between the GNOME 41 and freedesktop.org 21.08 runtimes, 388 MB out of 715 MB were deduplicated.
To add more, not only are the runtimes deduplicated, contents outside the runtimes are deduplicated too, as long as these files share the same hash (checksum). Alexander Larsson, the maintainer of Flatpak, explains more about it in details in this video.
Storage Usage§
We’re going to check the amount of storage runtimes are using on my system:
$ flatpak list --runtime --user | wc -l
57
Here, I have 57 runtimes installed.
Now, let’s look at the runtimes I have installed:
$ flatpak list --runtime --user
Name Application ID Version Branch Origin
Codecs com.github.Eloston.UngoogledChromium.Codecs stable flathub
Proton (community build) com.valvesoftware.Steam.CompatibilityTool.Proton 7.0-2 stable flathub
Proton experimental (community build) com.valvesoftware.Steam.CompatibilityTool.Proton-Exp 7.0-20220511 stable flathub
Proton-GE (community build) com.valvesoftware.Steam.CompatibilityTool.Proton-GE 7.17-1 stable flathub
gamescope com.valvesoftware.Steam.Utility.gamescope 3.11.28 stable flathub
steamtinkerlaunch com.valvesoftware.Steam.Utility.steamtinkerlaunch test steamtinkerlaunch-origin
Codecs org.audacityteam.Audacity.Codecs stable flathub
Codecs org.chromium.Chromium.Codecs stable flathub
Fedora Platform org.fedoraproject.Platform 35 f35 fedora
LSP org.freedesktop.LinuxAudio.Plugins.LSP 1.1.30 20.08 flathub
LSP org.freedesktop.LinuxAudio.Plugins.LSP 1.2.1 21.08 flathub
TAP-plugins org.freedesktop.LinuxAudio.Plugins.TAP 1.0.1 21.08 flathub
ZamPlugins org.freedesktop.LinuxAudio.Plugins.ZamPlugins 3.14 20.08 flathub
ZamPlugins org.freedesktop.LinuxAudio.Plugins.ZamPlugins 3.14 21.08 flathub
SWH org.freedesktop.LinuxAudio.Plugins.swh 0.4.17 21.08 flathub
Freedesktop Platform org.freedesktop.Platform 20.08.19 20.08 flathub
Freedesktop Platform org.freedesktop.Platform 21.08.13 21.08 flathub
i386 org.freedesktop.Platform.Compat.i386 21.08 flathub
Mesa org.freedesktop.Platform.GL.default 21.1.8 20.08 flathub
Mesa org.freedesktop.Platform.GL.default 21.3.8 21.08 flathub
default org.freedesktop.Platform.GL32.default 21.08 flathub
MangoHud org.freedesktop.Platform.VulkanLayer.MangoHud 0.6.6-1 21.08 flathub
vkBasalt org.freedesktop.Platform.VulkanLayer.vkBasalt 0.3.2.5 21.08 flathub
ffmpeg-full org.freedesktop.Platform.ffmpeg-full 21.08 flathub
i386 org.freedesktop.Platform.ffmpeg_full.i386 21.08 flathub
openh264 org.freedesktop.Platform.openh264 2.1.0 2.0 flathub
Freedesktop SDK org.freedesktop.Sdk 21.08.13 21.08 flathub
i386 org.freedesktop.Sdk.Compat.i386 21.08 flathub
.NET Core SDK extension org.freedesktop.Sdk.Extension.dotnet6 6.0.300 21.08 flathub
Free Pascal Compiler and Lazarus org.freedesktop.Sdk.Extension.freepascal 3.2.2 21.08 flathub
toolchain-i386 org.freedesktop.Sdk.Extension.toolchain-i386 21.08 flathub
GNOME Boxes Osinfo DB org.gnome.Boxes.Extension.OsinfoDb 20220214 stable flathub
GNOME Application Platform version 41 org.gnome.Platform 41 flathub
GNOME Application Platform version 42 org.gnome.Platform 42 flathub
GNOME Application Platform version Nightly org.gnome.Platform master gnome-nightly
i386 org.gnome.Platform.Compat.i386 41 flathub
i386 org.gnome.Platform.Compat.i386 42 flathub
GNOME Software Development Kit version 41 org.gnome.Sdk 41 flathub
GNOME Software Development Kit version 42 org.gnome.Sdk 42 flathub
GNOME Software Development Kit version Nightly org.gnome.Sdk master gnome-nightly
i386 org.gnome.Sdk.Compat.i386 41 flathub
i386 org.gnome.Sdk.Compat.i386 42 flathub
Adwaita dark GTK theme org.gtk.Gtk3theme.Adwaita-dark 3.22 flathub
adw-gtk3 Gtk Theme org.gtk.Gtk3theme.adw-gtk3 3.22 flathub
adw-gtk3-dark Gtk Theme org.gtk.Gtk3theme.adw-gtk3-dark 3.22 flathub
Kvantum theme engine org.kde.KStyle.Kvantum 1.0.1 5.15-21.08 flathub
KDE Application Platform org.kde.Platform 5.15-21.08 flathub
QGnomePlatform org.kde.PlatformTheme.QGnomePlatform 5.15 flathub
QGnomePlatform org.kde.PlatformTheme.QGnomePlatform 5.15-21.08 flathub
QtSNI org.kde.PlatformTheme.QtSNI 5.15 flathub
QtSNI org.kde.PlatformTheme.QtSNI 5.15-21.08 flathub
KDE Software Development Kit org.kde.Sdk 5.15-21.08 flathub
QGnomePlatform-decoration org.kde.WaylandDecoration.QGnomePlatform-decoration 5.15 flathub
QGnomePlatform-decoration org.kde.WaylandDecoration.QGnomePlatform-decoration 5.15-21.08 flathub
DXVK org.winehq.Wine.DLLs.dxvk 1.10.1 stable-21.08 flathub
Gecko org.winehq.Wine.gecko stable-21.08 flathub
Mono org.winehq.Wine.mono stable-21.08 flathub
This is a huge list of all the runtimes I have installed, ranging from different versions, branches, and more.
I install Flatpak apps with the --user
flag, meaning everything is installed per user. This means that all the Flatpak installs are located in the ~/.local/share/flatpak
directory.
I wrote a script that contrasts the size of Flatpak apps, runtimes or both. It checks the size without deduplication, with deduplication, and compression if applicable.
This script checks how many times a file hard links, and multiplies accordingly in a given Flatpak directory. For example, if a file hard links 10 times, then the script counts as 10 times the space. Then, it checks the actual size (with deduplication). Lastly, if using btrfs with transparent compression, the script will intelligently check the size with compression enabled.
With the help of this script, let’s look at how much data they’re taking up:
$ ./flatpak-dedup-checker --user --runtime
Directory: /var/home/TheEvilSkeleton/.local/share/flatpak/runtime
Size without deduplication: 36.22 GB
Size with deduplication: 13.07 GB (36% of 36.22 GB)
That’s it! Only 13.07 GB are used with deduplication for 57 runtimes, whereas 36.22 GB without. This is way less than 50%.
We can observe that deduplication is actually effective. A lot more than half is deduplicated because runtimes already share tons of files to begin with.
”"Disk space is cheap!"”§
They say disk space is cheap. This is not true, not for the root devices of modern computers. Built-in storage has in fact been shrinking.
Software has gotten so much slower and more bloated that operating systems no longer run acceptably on spinning rust. Laptop manufacturers are switching to smaller flash drives to improve performance while preserving margins. Budget laptops circa 2015 shipped with 256 GB or larger mechanical drives. Now in 2021 they ship with 120 GB flash. NVMe drives are around $100/TB and laptop manufacturers inflate these prices 500% or more so upgrading a new laptop can be pricey.
Chromebooks are even smaller as they push everything onto cloud storage. Smartphones are starting to run full-fledged Linux distributions. The Raspberry Pi 4 and 400 use an SD card as root device and have such fantastic performance that we’re on the verge of a revolution in low-cost computing. Surely Flatpak should be usable on these systems! There is no reason why a 16 GB root device shouldn’t fit every possible piece of non-game software we could want. Flatpak isn’t part of the revolution; it’s holding it back.
Built-in storage have definitely become smaller. However, flash storage have higher physical density than hard drives because of built-in compression and deduplication in SSD controllers and flash storage. Simply put, data take less space on flash memories compared to hard drives.
Additionally, we can enable btrfs transparent compression to save up a lot of space. Fedora Linux comes with zstd:1 (zstd level 1) compression to make data take less space, which is the one I am going to use in the following example.
Let’s contrast the size of the results above, but now with compression:
$ ./flatpak-dedup-checker --user --runtime
Directory: /var/home/TheEvilSkeleton/.local/share/flatpak/runtime
Size without deduplication: 36.22 GB
Size with deduplication: 13.07 GB (36% of 36.22 GB)
Size with compression: 9.41 GB (25% of 36.22 GB. 71% of 13.07 GB)
Even better. Only with deduplication, runtimes take 36% of 34.22 GB. Pair it with zstd:1, it literally takes a quarter.
Let’s do the same with all the installed apps:
$ flatpak list --app --user | wc --lines
79
I have 79 apps installed. Here’s the list of all the apps installed:
$ flatpak list --app --user
Name Application ID Version Branch Origin
Decoder com.belmoussaoui.Decoder 0.2.2 stable flathub
Brave Browser com.brave.Browser 1.38.115 stable flathub
Discord com.discordapp.Discord 0.0.17 stable flathub
Discord Canary com.discordapp.DiscordCanary 0.0.135 beta flathub-beta
Mindustry com.github.Anuken.Mindustry 126.2 stable flathub
ungoogled-chromium com.github.Eloston.UngoogledChromium 101.0.4951.64 stable flathub
Notepad Next com.github.dail8859.NotepadNext v0.5.1 stable flathub
Tor Browser Launcher com.github.micahflee.torbrowser-launcher 0.3.5 stable flathub
waifu2x-ncnn-vulkan com.github.nihui.waifu2x-ncnn-vulkan 20220419 stable flathub
Czkawka com.github.qarmin.czkawka 4.1.0 stable flathub
Avvie com.github.taiko2k.avvie 2.1 stable flathub
Flatseal com.github.tchx84.Flatseal 1.7.5 stable flathub
EasyEffects com.github.wwmm.easyeffects 6.2.5 stable flathub
NewsFlash com.gitlab.newsflash 1.5.1 stable flathub
Google Chrome com.google.Chrome 101.0.4951.41-1 beta flathub-beta
Extension Manager com.mattjakeman.ExtensionManager 0.3.0 stable flathub
Microsoft Edge com.microsoft.Edge 101.0.1210.39-1 stable flathub
OBS Studio com.obsproject.Studio 27.2.4 stable flathub
BlackBox com.raggesilver.BlackBox 42.alpha0 master blackbox-origin
Bottles com.usebottles.bottles 2022.5.2-trento-3 stable flathub
Steam com.valvesoftware.Steam 1.0.0.74 stable flathub
Visual Studio Code com.visualstudio.code 1.67.0-1651667246 stable flathub
Fragments de.haeckerfelix.Fragments 2.0.2 stable flathub
Boop-GTK fyi.zoey.Boop-GTK 1.6.0 stable flathub
Element im.riot.Riot 1.10.12 stable flathub
Amberol io.bassi.Amberol 0.6.1 stable flathub
youtubedl-gui io.github.JaGoLi.ytdl_gui 3.0 stable flathub
Celluloid io.github.celluloid_player.Celluloid 0.23 stable flathub
Mousai io.github.seadve.Mousai 0.6.6 stable flathub
LibreWolf io.gitlab.librewolf-community 100.0-2 stable flathub
Lutris net.lutris.Lutris 0.5.10.1 beta flathub-beta
Poedit net.poedit.Poedit 3.0.1 stable flathub
Color Picker nl.hjdskes.gcolor3 2.4.0 stable flathub
Audacity org.audacityteam.Audacity 3.1.3 stable flathub
Chromium Web Browser org.chromium.Chromium 101.0.4951.64 stable flathub
Chromium app base org.chromium.Chromium.BaseApp 21.08 flathub
Electron2 app base org.electronjs.Electron2.BaseApp 21.08 flathub
Fedora Media Writer org.fedoraproject.MediaWriter 4.2.2 stable fedora
Flatpak External Data Checker org.flathub.flatpak-external-data-checker stable flathub
appstream-glib org.freedesktop.appstream-glib stable flathub
Feeds org.gabmus.gfeeds 1.0.3 stable flathub
GNU Image Manipulation Program org.gimp.GIMP 2.99.10 beta flathub-beta
Adwaita Demo org.gnome.Adwaita1.Demo 1.2.alpha master gnome-nightly
Boxes org.gnome.Boxes 42.0 stable flathub
Builder org.gnome.Builder 42.0 stable flathub
Calendar org.gnome.Calendar 42.0 stable flathub
Contacts org.gnome.Contacts 42.0 stable flathub
Web org.gnome.Epiphany.Devel 42~beta master devel-origin
File Roller org.gnome.FileRoller 3.42.0 stable flathub
Firmware org.gnome.Firmware 42.1 stable flathub
Fractal org.gnome.Fractal.Devel 5.alpha master gnome-nightly
Geary org.gnome.Geary 40.0 stable flathub
Notes org.gnome.Notes 40.1 stable flathub
Text Editor org.gnome.TextEditor 42.1 stable flathub
Weather org.gnome.Weather 42.0 stable flathub
Clocks org.gnome.clocks 42.0 stable flathub
Contrast org.gnome.design.Contrast 0.0.5 stable flathub
Image Viewer org.gnome.eog 42.1 stable flathub
Fonts org.gnome.font-viewer 42.0 stable flathub
gitg org.gnome.gitg 41 stable flathub
Identity org.gnome.gitlab.YaLTeR.Identity 0.3.0 stable flathub
Iotas org.gnome.gitlab.cheywood.Iotas 0.1.1 stable flathub
Apostrophe org.gnome.gitlab.somas.Apostrophe 2.6.3 stable flathub
Inkscape org.inkscape.Inkscape 1.1.2 stable flathub
Kdenlive org.kde.kdenlive 22.04.0 stable flathub
Krita org.kde.krita 5.0.2 stable flathub
LibreOffice org.libreoffice.LibreOffice 7.3.3.2 stable flathub
Thunderbird org.mozilla.Thunderbird 91.9.0 stable flathub
Firefox org.mozilla.firefox 100.0 stable flathub
Olive org.olivevideoeditor.Olive 0.1.2 stable flathub
ONLYOFFICE Desktop Editors org.onlyoffice.desktopeditors 7.0.1 stable flathub
Helvum org.pipewire.Helvum 0.3.4 stable flathub
PolyMC org.polymc.PolyMC 1.2.2 stable flathub
PulseAudio Volume Control org.pulseaudio.pavucontrol 5.0 stable flathub
qBittorrent org.qbittorrent.qBittorrent 4.4.2 stable flathub
QOwnNotes org.qownnotes.QOwnNotes 22.5.0 stable flathub
Tenacity org.tenacityaudio.Tenacity nightly tenacity
Wine org.winehq.Wine 7.0 stable-21.08 flathub
Commit re.sonny.Commit 3.2.0 stable flathub
Let’s check the amount of storage they take without deduplication, with deduplication, and with deduplication and compression:
$ ./flatpak-dedup-checker --user --app
Directory: /var/home/TheEvilSkeleton/.local/share/flatpak/app
Size without deduplication: 11.16 GB
Size with deduplication: 9.78 GB (87% of 11.16 GB)
Size with compression: 7.81 GB (69% of 11.16 GB. 79% of 9.78 GB)
Apps already take very little amount of space. Since they generally contain nonidentical files, the likelihood of deduplication to occur is less than with runtimes. With deduplication, 87% of the nondeduplicated 11.16 GB is used. Pair it with zstd:1, 69% of 11.16 GB.
Now, with runtimes and apps combined:
$ ./flatpak-dedup-checker --user
Directories: /var/home/TheEvilSkeleton/.local/share/flatpak/{runtime,app}
Size without deduplication: 47.38 GB
Size with deduplication: 22.75 GB (48% of 47.38 GB)
Size with compression: 17.17 GB (36% of 47.38 GB. 75% of 22.75 GB)
We can observe here that the compression is effective. This is also a driving force for Fedora Linux to push btrfs to users, so we can take advantage of modern features like compression. Hopefully more and more distributions follow the same footstep.
“Memory Usage, Startup Time”§
A bigger problem is that these apps can actually take several seconds to start up. They have to load all their own libraries from disk instead of using what’s already on the system, already in memory.
This is assuming that the user has the same apps installed on the system and as a Flatpak and frequently loads both. I can only imagine that there is a tiny percentage of users that have both formats (Flatpak and traditional) installed and use both frequently. Otherwise, there shouldn’t be a problem if these apps are primarily used as a Flatpak.
Distributions that heavily push Flatpak, like Fedora Silverblue/Kinoite, Endless OS and elementaryOS, strictly push Flatpak for apps. As a side effect, they come with a base install. As an example, an Endless OS install takes roughly 4.2 GB, according to Will Thompson on “On Flatpak disk usage and deduplication”.
“Security”§
Flatpak allows apps to declare that they need full access to your filesystem or your home folder, yet graphical software stores still claim such apps are sandboxed. This has been discussed before. Here’s what happens when I search GIMP in the Software app on a fresh install of Fedora 34:
This has been discussed before too. I also want to add that this is a GNOME Software issue for not displaying correctly, rather than Flatpak being at fault. On another note, this has been fixed since GNOME 41:
Regardless, I personally believe that it is unfair to blame the backend utility (Flatpak) for an issue caused by the frontend (GNOME Software). The flatpak
command-line utility makes it very clear about the permissions GIMP or any other app is going to use by default:
$ flatpak install org.gimp.GIMP
org.gimp.GIMP permissions:
ipc network x11 dri file access [1]
dbus access [2] tags [3]
[1] /tmp, host, xdg-config/GIMP, xdg-config/gtk-3.0, xdg-run/gvfs, xdg-run/gvfsd
[2] org.freedesktop.FileManager1, org.gnome.Shell.Screenshot, org.gtk.vfs, org.gtk.vfs.*,
org.kde.kwin.Screenshot
[3] stable
ID Branch Op Remote Download
1. org.gimp.GIMP stable i flathub < 121.3 MB
Proceed with these changes to the user installation? [Y/n]:
Flatpak itself was always blatant with permissions and I don’t think it’s fair to criticize them when they didn’t cause it.
”"It’s better than nothing!"”§
Flatpak and Snap apologists claim that some security is better than nothing. This is not true. From a purely technical perspective, for apps with filesystem access the security is exactly equal to nothing. In reality it’s actually worse than nothing because it leads people to place more trust than they should in random apps they find on the internet.
From a purely technical perspective, Flatpak does have some security benefits too, be it with filesystem=host/home
or not. Filesystem access does not automatically mean that the app in question has access to everything.
First of all, Flatpak apps cannot see the content of other Flatpak apps. Let’s contrast what the host shell sees and what the shell inside the GIMP container sees under ~/.var/app
, where all user configuration in Flatpak apps lie in.
Let’s first check what the host shell sees:
$ ls ~/.var/app | wc --lines
83
$ ls ~/.var/app
com.belmoussaoui.Decoder com.microsoft.Edge org.chromium.Chromium org.gnome.Contacts org.gnome.gitlab.cheywood.Iotas org.mozilla.Firefox
com.brave.Browser com.obsproject.Studio org.cubocore.CoreArchiver org.gnome.design.Contrast org.gnome.gitlab.somas.Apostrophe org.mozilla.firefox
com.discordapp.Discord com.raggesilver.Terminal org.fedoraproject.MediaWriter org.gnome.eog org.gnome.gitlab.YaLTeR.Identity org.olivevideoeditor.Olive
com.discordapp.DiscordCanary com.usebottles.bottles org.flathub.flatpak-external-data-checker org.gnome.eog.Devel org.gnome.NautilusDevel org.onlyoffice.desktopeditors
com.github.Anuken.Mindustry com.valvesoftware.Steam org.freedesktop.appstream-glib org.gnome.Epiphany.Devel org.gnome.Notes org.pipewire.Helvum
com.github.dail8859.NotepadNext de.haeckerfelix.Fragments org.gabmus.gfeeds org.gnome.Evince org.gnome.Screenshot org.polymc.PolyMC
com.github.Eloston.UngoogledChromium fyi.zoey.Boop-GTK org.gimp.GIMP org.gnome.FileRoller org.gnome.TextEditor org.pulseaudio.pavucontrol
com.github.micahflee.torbrowser-launcher im.riot.Riot org.gnome.Adwaita1.Demo org.gnome.Firmware org.gnome.Totem org.qbittorrent.qBittorrent
com.github.nihui.waifu2x-ncnn-vulkan io.bassi.Amberol org.gnome.Boxes org.gnome.font-viewer org.gnome.Weather org.qownnotes.QOwnNotes
com.github.tchx84.Flatseal io.github.celluloid_player.Celluloid org.gnome.Builder org.gnome.Fractal.Devel org.inkscape.Inkscape org.tenacityaudio.Tenacity
com.github.wwmm.easyeffects io.github.JaGoLi.ytdl_gui org.gnome.Calculator org.gnome.FractalDevel org.kde.alligator org.winehq.Wine
com.gitlab.newsflash io.github.seadve.Mousai org.gnome.Calendar org.gnome.Geary org.kde.kdenlive re.sonny.Commit
com.google.Chrome net.poedit.Poedit org.gnome.Characters org.gnome.gedit org.kde.krita us.zoom.Zoom
com.mattjakeman.ExtensionManager nl.hjdskes.gcolor3 org.gnome.clocks org.gnome.gitg org.libreoffice.LibreOffice
We can observe that the host sees everything inside ~/.var/app
.
Let’s check inside the GIMP container:
$ flatpak run --command=bash org.gimp.GIMP
[📦 org.gimp.GIMP]$ ls ~/.var/app
org.gimp.GIMP
Unlike the host shell, the GIMP container can only see ~/.var/app/org.gimp.GIMP
, which is where the GIMP configurations live. GIMP cannot see my Geary, GNOME Contacts or other Flatpak apps’ configurations by default, even with filesystem=host
, meaning it will be much harder for GIMP to tamper with other apps’ data and read from them.
Additionally, these apps don’t have access to every single API or framework in the system by default. I have my computer connected and synced up with my Nextcloud instance, Google and Microsoft accounts. For my computer to communicate with my accounts, it uses the OnlineAccounts framework. This also allows apps like GNOME Contacts, Notes and more to sync my contacts, notes and other information. GNOME Contacts has the org.gnome.OnlineAccounts=talk
permission, which means that it can “talk” to the framework and access these information, whereas GIMP doesn’t.
To confirm, let’s check if GIMP, an app that comes with filesystem=host
, has the org.gnome.OnlineAccounts=talk
permission:
$ flatpak info --show-permissions org.gimp.GIMP
[Context]
shared=network;ipc;
sockets=x11;wayland;fallback-x11;
devices=dri;
filesystems=xdg-config/GIMP;xdg-config/gtk-3.0;/tmp;xdg-run/gvfsd;host;xdg-run/gvfs;
[Session Bus Policy]
org.kde.kwin.Screenshot=talk
org.gtk.vfs.*=talk
org.gnome.Shell.Screenshot=talk
org.freedesktop.FileManager1=talk
We notice that there is no org.gnome.OnlineAccounts=talk
here. This means that without this permission, it’s much harder for GIMP to communicate with the OnlineAccounts framework and therefore it cannot successfully fetch my contacts, notes or other sorts of information to accounts I am connected in.
Needless to say, it is definitely a problem that filesystem=host/home
can write to sensitive locations, but the fact that it requires extra steps for GIMP to gain access to my other personal information means that Flatpak can prevent bad actors a little bit with filesystem=host/home
. Also, the majority of apps don’t come with those permissions. In the realm of security, 100% security doesn’t exist, but we can always take a step closer, which is exactly what Flatpak does.
Furthermore, we can use Flatseal to manage these permissions, if feeling uncomfortable with the defaults. While I do admit that this is not a great approach, it certainly is the best option for now. The alternative is manually configuring bubblewrap, Firejail or AppArmor, which requires a lot more time and knowledge than Flatseal. Flatseal also neatly documents the main permissions, to help users understand what they are about to change.
“Permissions and Portals”§
Flatpak is working on a fine-grained permission system to improve the security of its sandbox. Permissions are things like whether the app is allowed to access the microphone or the printer. Portals are things like a file open dialog that runs outside the sandbox, so the app in the sandbox gets only the file the user chose.
Flatpak documents these Portals and provides libportal, a client library to access them. However this isn’t really intended for individual apps. It’s all meant to be integrated in the toolkits. From the documentation:
Interface toolkits like GTK3 and Qt5 implement transparent support for Portals, meaning that apps don’t need to do any additional work to use them (it is worth checking which Portals each toolkit supports).
Apparently, developing client APIs for apps themselves is antithetical to Flatpak’s mission. They want the apps running on Flatpak to be unaware of Flatpak. They would rather modify the core libraries like GTK to integrate with Flatpak. So for example if you want to open a file, you don’t call a Flatpak API function to get a file or request permissions. Instead, you call for an ordinary GTK file open dialog and your Flatpak runtime’s GTK internally does the portal interaction with the Flatpak service (using all sorts of hacks to let you access the file “normally” and pretend you’re not sandboxed.)
This is the most complicated and brittle way to implement this. It’s also not at all how other sandboxed platforms work. If I want file access permissions on Android, I don’t just try to open a file with the Java File API and expect it to magically prompt the user. I have to call Android-specific APIs to request permissions first. iOS is the same. So why shouldn’t I be able to just call
flatpak_request_permission(PERMISSION)
and get a callback when the user approves or declines?
XDG Desktop Portals (Portals for short) are designed to be standards and not Flatpak specific. This means that Portals can be utilized outside of Flatpak, i.e. system packages or even with Snap. This also means that we can take advantage of these Portals to better integrate with the desktop.
A notorious example is the file picker problem on Linux. For the longest time, Firefox and Chromium based browsers (including Electron) have been using the GTK file picker. This means, that if you were using Plasma at that time, these browsers were using the GTK file picker instead of the KDE file picker, which made them look out of place depending on the desktop in use.
This was later solved with the XDG FileChooser portal. The FileChooser portal makes apps open the host file picker instead of the hardcoded file picker the toolkit or framework is using. Nowadays, if you use Firefox or Google Chrome on Plasma, Flatpak or not, and you decide to open the file picker within these apps, then they will open the KDE file picker and not the previously hardcoded GTK file picker. Likewise, Kdenlive, a KDE app, opens the GTK file picker when using GNOME, and not the KDE file picker.
Another huge benefit with Portals is that they are automatically in use as soon as the app developer upgrades to a version of the toolkit or framework wherein support of the portal is included, therefore being transparent. Last year, Electron started supporting the FileChooser portal. Element, a Matrix client that uses Electron, upgraded to a newer version of Electron that supports the FileChooser portal. After that upgrade, Element “magically” started opening the host’s file picker and not the previously hardcoded GTK file picker. So, if you are using Plasma, Element should now open the KDE file picker and not the GTK file picker. It literally can’t get easier than that.
In contrast, I can only imagine that Flatpak developers developing Flatpak specific, i.e. nonstandard, APIs would force individual app developers to integrate these APIs and continuously maintain them. This would cause duplicated work among app developers, and may also force individual developers to maintain Flatpak specific APIs atop the APIs they are already using, instead of using one for every use case. And worst of all, this would only work with Flatpak, so traditional apps wouldn’t have the luxury of opening the desktop’s file picker.
The approach the Flatpak developers are taking at the moment is a standardized, transparent and easily integrated fashion, where app developers have to put very little to no effort to get these APIs working. Already the majority of developers don’t prioritize the Linux desktop, expecting adoption on the Linux desktop by asking developers to implement and maintain different sets of APIs solely for Flatpak won’t do any help.
This is why. Fedora is auto-converting all of their rpm apps to Flatpak. In order for this to work, they need the Flatpak permission system and Flatpak in general to require no app changes whatsoever.
Why on Earth would they do a mass automatic conversion of apps? Your guess is as good as mine. The video claims that Fedora’s apps are higher quality than upstream, and Fedora makes their Flatpaks available on older distributions. I think it’s more likely they just want huge numbers of auto-converted apps to make it look like Flatpak is useful. Whatever the reason, it’s clear that this requirement has influenced many of their poor design decisions.
This is… unrelated? The previous slides in the presentation have no correlation with Portals whatsoever. This is the Fedora Project’s decision solely.
And logically, if Flatpak developers decided to create Flatpak specific APIs, and app developers integrated these APIs in their apps, then these converted RPMs would have no problem running those apps inside Flatpak containers, because upstream would already support these Flatpak specific APIs. Calling Flatpak specific APIs wouldn’t affect Fedora Flatpaks at all.
Since Fedora Flatpaks converts RPMs from the Fedora repositories to Flatpak apps, it is much easier to trust and audit from a Fedora Project developer and maintainer perspective. Furthermore, these RPMs already comply with all Fedora Project’s conducts and standards. They’re all built inside the Fedora Project’s infrastructure and based on RPMs that are maintained by Fedora Project maintainers. Flathub, on the other hand, is independent and unaffiliated with the Fedora Project. This also makes auditing harder for the Fedora Project maintainers.
“Identifier Clashes”§
So Fedora auto-converts all its apps to Flatpak. Does it at least namespace them to something specific to Fedora?
No, it doesn’t. Fedora publishes its Flatpak of GIMP as
org.gimp.GIMP
. This conflicts with the officialorg.gimp.GIMP
published by the GIMP developers on Flathub. On a fresh install of Fedora 34, if you add the Flathub repository and typeflatpak install org.gimp.GIMP
, you get prompted for which one to install:[nick@fedora active]$ flatpak install org.gimp.GIMP Looking for matches… Remotes found with refs similar to ‘org.gimp.GIMP’: 1) ‘fedora’ (system) 2) ‘flathub’ (system) Which do you want to use (0 to abort)? [0-2]:
If you choose option 1, you get a build of GIMP with Fedora’s patches that uses the 650 MB Fedora 35 runtime. If you choose option 2, you get a different build of GIMP that uses the 1.8 GB freedesktop.org GNOME runtime.
Isn’t the whole point of reverse DNS that the org.gimp prefix is reserved for people who actually own the gimp.org domain? How can Fedora justify publishing apps while masquerading as the upstream developers? If major Linux distributions won’t even respect DNS, who will?
The point of the reverse DNS notation is to use the domain name of the author of the app, not the author of the packager.
Needless to say, this is indeed a problem. The decentralized nature of Flatpak gives the freedom to Flatpak remotes to use the same app ID, which as a side effect may also result to identifier clashes. Although, this still prevents apps from the having same name more than without app IDs.
“Services”§
All of these app packaging systems require that the user have some service installed on their PC before any packages can be installed.
AppImage, to its credit, technically does not require a service to run apps, but it doesn’t integrate with the desktop without it. I needed to use an AppImage app for a while and my solution was to just leave it in my
~/Downloads
folder and double click it from my file manager to run it. This is a terrible user experience.All of the desktop integration (launcher entries, mimetypes, icons, updates) is provided by either appimaged or AppImageLauncher, one of which must be installed by the user for any of this to work. So in practice, AppImage is no different than any of our other solutions: it requires a service to be usable.
There is one important key missing: store integration. AppImage bundles don’t (and won’t anytime soon) integrate with software stores like GNOME Software or Discover. GNOME Software and Discover take care of managing Flatpak apps and system packages simultaneously, whereas AppImageHub is for AppImage specifically.
Most AppImage bundles need a big minimum requirement. They don’t bundle glibc or other core dependencies. Additionally, they might not even come with higher level dependencies bundled that would make an app actually functional without relying a lot on the host. Many of them will assume that some dependencies are already installed and have the right version on the host.
This means that most AppImage bundles are not actually universal, and it gets harder to use them depending on the distribution you are using. If you are using a musl based distribution, the majority of AppImage bundles won’t work, because they need glibc. Likewise, if you use an immutable distribution, chances are they won’t come with many lower and higher level dependencies, because Flatpak already takes care of that. Flatpak is compatible in the majority of desktop cases. Even the Steam Deck uses Flatpak by default, because Flatpak ships with lower and higher level dependencies.
“Is Flatpak Fixable?”§
If the Flatpak developers truly want an app distribution system that rivals Android and iOS, the sandbox, permissions and portal system should be the only focus.
They should:
- Abandon everything related to runtimes, and instead mount the native
/usr
(or a restricted set of core libraries from/usr
) read-only into each container;
/usr
is a directory that is unique per install the majority of the time, because users install different packages. As a result, Flatpak will assume that some libraries and dependencies are already installed. This would recreate the same problems as AppImage and thus won’t make them universal, which would also defeat the purpose of Flatpak.
Runtimes ensure that core dependencies are always available on any given system, and more importantly, the right version.
- Build a fine-grained user-interactive runtime permission system that requires the app to make Flatpak-specific API calls to activate permission dialogs; and
This is exactly what Flatpak is doing, the only difference is these “Flatpak-specific API calls” are Portals, which are also standards. As time goes by, we’ll start seeing more and more apps that use Portals. GTK apps already use Portals, so do Qt apps. Firefox, Chromium based browsers and Electron started supporting some of the Portals too, and so on.
- Deprecate install-time permissions (especially filesystem access) and remove all apps from Flathub that use them.
Mass adoption doesn’t happen in 10 days. It mostly depends on app developers’ priorities. Right now, we rely on install-time (static) permissions because many framework developers don’t deem Portals a priority. This problem is not exclusive to Flatpak, as it also happens with Wayland, Windows Store, and many other newer technologies on other platforms. Modern video games still on 32-bit libraries to this day. This is much easier said than done, and it’s literally impossible to make apps that were designed for unsandboxed environments run in its antithesis environment without expecting issues.
Anything that requires transitioning or adapting to a different technology requires time and effort. Flatpak is not magic, neither are Wayland, PipeWire and others.
Even with filesystem permissions, there are still security benefits. These apps typically don’t have access to all the APIs and don’t have access to individual Flatpak apps’ data. Furthermore, managing permissions are also much easier than the alternatives because the documentation is available and the interface is easy to use.
The container aspect is also really helpful, because it makes upgrading systems much easier. Instead of relying on PPAs, Copr and the likes, Flatpak apps are independently updated between major versions and only need to be packaged once for everyone.
On another note, avoiding static permissions is indeed a priority, because we want to ideally switch to Portals entirely, as mentioned by Alexander Larsson in this presentation.
Under this system, apps would be encouraged to statically link many of their dependencies, but use the system GTK/Qt/SDL, OpenGL/Vulkan, OpenSSL/curl, and other large or security-critical libraries. The community could maintain guidelines and wrappers to make apps that dynamically link against the system libraries cross-version and cross-distribution. Apps would be expected to make changes to run sandboxed and request permissions directly through a Flatpak client API.
This, again, causes issues with universality. These dependencies may be using older, newer, patched, etc. variants depending on the distribution, as opposed to Flatpak which uses the same everywhere. I’ve recently stumbled upon a user who had issues with Bottles failing to render the font. This was caused by using a patched version of GTK. The issue was later resolved, but we can observe that simple patches can cause usability issues. Let alone version differences.
“Conclusion”§
If you are a Linux distribution maintainer, please understand what all of these solutions are trying to accomplish. All your hard work in building your software repository, maintaining your libraries, testing countless system configurations, designing a consistent user experience… they are trying to throw all of that away. Every single one of these runtime packaging mechanisms is trying to subvert the operating system, replacing as much as they can with their own. Why would you support this?
Flatpak’s goal is not to “throw all of that away”. Rather, it is to avoid doing duplicated work and give more room for distribution developers to innovate their distribution, instead of spending the majority of the time to package software and continuously maintain them. Alexander Larsson made a presentation explaining it in details.
This is also why Fedora Silverblue/Kinoite is improving very quickly. Fedora Silverblue/Kinoite is entirely different from most distributions because of its immutable nature. Since it relies mainly on Flatpak and Toolbx, there are a lot more room to improve core utilities like rpm-ostree
(Fedora Silverblue/Kinoite’s package manager). Another prime example is SteamOS.
Conclusion§
In conclusion, I believe that the author of the article has misunderstood many aspects of Flatpak and quickly drew conclusions.
Before Flatpak was first announced, there were already plenty of issues on the Linux desktop: X11, PulseAudio, fragmentation, etc. As per the fragmentation, packages are generally built against different toolchains and different libraries and dependencies. There are endless of possibilities of software not working as intended on any distribution at any given time.
These are real world issues on the Linux desktop, and we can clearly see that Flatpak developers are doing an outstanding job to solve them; properly too: Flatpak was first announced in 2015 as xdg-app, and not even a decade later, GTK apps work excellently (and sometimes even better) with Flatpak than their system package counterpart. Complex apps like Bottles, Firefox and any Chromium based browsers work very well inside Flatpak. The Steam Deck ships and primarily uses Flatpak on SteamOS. Fedora Silverblue/Kinoite, Endless OS and elementaryOS primarily use Flatpak as well.
Is Flatpak perfect? No. We still heavily rely on static permissions. However, as time goes by, I believe more and more frameworks and toolkits will start using Portals. More apps that use these frameworks and toolkits will start supporting Portals with very minimal work put into them, and apps will be designed to be secure by default on the operating system because Portals take care of the majority of the security problems already.
- Edit 1: remove mentions of TRIM. It cleans up deleted data and therefore doesn’t really benefit with reducing data (credit to re:fi.64)
- Edit 2: mention partial installs (credit to RushingAlien)
- Edit 3: improve wording