Snap, Flatpak, and AppImage
Topic 39

Snap, Flatpak, and AppImage

Package Management

Snap, Flatpak, and AppImage are distribution-independent package formats. Instead of relying on the shared libraries that apt installs into /usr, each format ships an application together with the dependencies it needs, so the same artifact runs on Debian, Ubuntu, Fedora, and Arch without a per-distribution rebuild. Snap and Flatpak also run the application inside a sandbox; AppImage does not by default.

The operational cost is duplication. A Flatpak GTK app pulls in a runtime of 300-700 MB that several apps can share, but a Snap bundles its own copy of most libraries, so the same program can occupy 2-5x the disk of its .deb equivalent. First launch is slower too: a Snap or Flatpak has to set up its mount namespace and decompress a SquashFS image, adding roughly 0.5-2 seconds of cold-start latency that a natively linked binary does not pay.

Snap and snapd

Snap is Canonical's format, managed by the snapd daemon that ships preinstalled on Ubuntu Desktop and Ubuntu Server. A snap is a SquashFS image mounted read-only under /snap; you can see the loopback mounts with mount | grep snap. Confinement is enforced by AppArmor and seccomp, with three levels: strict (full sandbox), classic (no confinement, full host access), and devmode (sandbox with violations logged but allowed).

# install, list, inspect connections, and remove
snap install firefox
snap list
snap connections firefox
snap remove --purge firefox

Snaps update automatically. snapd refreshes installed snaps up to four times a day from the Snap Store. You cannot turn the refresh machinery off, but since snapd 2.58 you can hold updates indefinitely — snap refresh --hold with no duration holds forever, and the older refresh.hold option defers to a fixed date up to 90 days out. On classic Ubuntu snapd keeps two revisions of each snap by default (refresh.retain=2: the current one plus one previous), so snap revert can roll back. The principal objection from the community is that the Snap Store backend is closed-source and operated only by Canonical, so unlike apt repositories or Flathub you cannot self-host an equivalent store.

Flatpak and Flathub

Flatpak is a vendor-neutral format hosted primarily on Flathub, a community repository. Its key idea is the shared runtime: applications declare a base such as org.freedesktop.Platform or org.gnome.Platform, and many apps reuse the one installed copy. Sandboxing uses bubblewrap for namespace isolation, and access to resources outside the sandbox — files, the camera, the network — goes through portals, D-Bus services that prompt the user or apply a policy.

# add Flathub, install, then inspect and tighten permissions
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install flathub org.gimp.GIMP
flatpak info --show-permissions org.gimp.GIMP
flatpak override --nofilesystem=home org.gimp.GIMP

Permissions are inspectable and overridable per app, which makes Flatpak the most auditable of the three: flatpak override narrows or widens an app's filesystem and device access without touching the package. Updates are pulled, not pushed — nothing changes until you run flatpak update — and the OSTree-based store deduplicates files across versions so a 2 GB app does not cost 2 GB per update.

AppImage and single-file distribution

An AppImage is a single executable file containing the application and its dependencies as a compressed SquashFS filesystem with a runtime header. There is no install step, no daemon, and no root: you make the file executable and run it. This makes AppImage the simplest format to distribute outside any store — a vendor publishes one file on a download page.

# download, make executable, run — no root, no package manager
chmod +x ./Application-x86_64.AppImage
./Application-x86_64.AppImage
# extract its contents without running it
./Application-x86_64.AppImage --appimage-extract

The trade-off is that AppImage provides no sandbox of its own — the binary runs with your full user privileges unless you wrap it in firejail or bwrap yourself. It also has no update mechanism beyond the optional AppImageUpdate tool and no central registry, so security patches depend entirely on the vendor and on you replacing the file. On modern Ubuntu, AppImages require libfuse2 because Ubuntu 22.04 and later ship FUSE 3 by default while older AppImages link against FUSE 2.

When to Use Each Format

Reach for the native apt package first: it is the smallest on disk, integrates with unattended security updates, and is what server tooling expects. Use a universal format only when the .deb is absent, too old, or you need a version the distribution will not backport.

Among the three, pick Flatpak for desktop GUI apps where you want auditable per-app permissions and shared runtimes; pick Snap when the upstream ships only a snap or when you want auto-updating CLI tools on Ubuntu; pick AppImage for a portable, install-free binary you can run on any glibc-based distribution, accepting that it is unsandboxed and self-updating at best.

Common Mistakes
  • Installing the Snap of a server daemon and then being surprised when it auto-refreshes mid-day. On production hosts, set snap refresh --hold or schedule a maintenance window with refresh.timer rather than assuming you control upgrades like apt.
  • Running an AppImage and assuming it is sandboxed. AppImage has no confinement by default; the binary has the same access to $HOME and your SSH keys as any other process you start.
  • Granting a Flatpak --filesystem=home to fix a "cannot open file" error. That removes the sandbox's main protection; scope it to a directory like --filesystem=~/Documents instead.
  • Expecting a strictly-confined Snap to read arbitrary paths. A strict snap cannot see /mnt or removable media until you connect the removable-media interface with snap connect.
  • Shipping a single Snap or Flatpak per machine and ignoring duplicated runtimes. Five Snaps that each bundle their own GNOME libraries cost far more disk than five .deb packages sharing /usr.
  • Downloading an old AppImage on Ubuntu 22.04+ and getting a cryptic FUSE error. The fix is apt install libfuse2, not chasing a phantom corrupt-file problem.
Best Practices
  • Prefer the apt package on servers; reserve universal formats for desktops and for software with no maintained .deb.
  • Audit Flatpak permissions with flatpak info --show-permissions before trusting an app, and tighten them with flatpak override.
  • Hold Snap refreshes on production with snap refresh --hold and test the new revision before releasing the hold.
  • Verify AppImage downloads against the vendor's published SHA-256 or signature, since there is no store to vouch for them.
  • Install libfuse2 on Ubuntu 22.04 and later before running AppImages built against FUSE 2.
  • Reclaim disk by removing old Snap revisions with snap set system refresh.retain=2 and pruning unused Flatpak runtimes with flatpak uninstall --unused.
  • Connect only the Snap interfaces an app needs with snap connect rather than reaching for a classic install that disables confinement entirely.
Comparable toolsmacOS — self-contained .app bundles, the closest desktop parallel to a single-file AppImageWindows — MSIX (sandboxed) and winget; bundled-dependency installers like the older ClickOnceNix / Guix — reproducible per-app dependency closures without a sandbox, an alternative answer to the same dependency problem

Knowledge Check

Which of the three formats provides no sandbox by default?

  • AppImage — the binary runs with your full user privileges unless you wrap it in firejail or bwrap
  • A Snap installed under strict confinement with AppArmor and seccomp enforcing, so it reaches the rest of the system only through interfaces you explicitly connect
  • A Flatpak that mediates all resource access through D-Bus portals and bubblewrap, prompting before it can reach files or devices outside its own sandbox
  • All three formats are fully sandboxed by default out of the box, each confining its binary to its own bundle and brokering every outside request through the host

What is the principal community objection to Snap, as opposed to Flatpak?

  • The Snap Store backend is closed-source and operated only by Canonical, so you cannot self-host an equivalent store
  • Snaps cannot be confined or sandboxed at all, even under strict mode, so every installed snap runs with the same unrestricted access to your files and devices that a native binary has
  • Snap packages refuse to install or run on any non-Ubuntu distribution, so a snap built for one host is locked to Ubuntu and cannot be carried to Fedora or Arch
  • Snap has no mechanism to roll back to a previous revision after a bad refresh

Why does a Flatpak app typically consume less disk than the equivalent Snap?

  • Flatpak apps share an installed runtime, while a Snap bundles its own copy of most libraries
  • Flatpak compresses its application images while Snap stores them uncompressed on disk, so the same program occupies far fewer blocks once unpacked
  • Flatpak installs into the shared /usr tree the same way a native .deb does
  • Flatpak deletes the application from disk after each run and re-fetches it next time

On a production Ubuntu server, why prefer the apt package over a Snap for a long-running daemon?

  • The apt package fits controlled, scheduled patching instead of auto-refreshing up to four times a day on Canonical's clock
  • Snaps are technically unable to run a long-lived background service at all, so a daemon packaged as a snap exits as soon as the launching shell closes and cannot stay resident
  • Snaps require an active graphical desktop session to be installed on the host, so a headless server with no display manager cannot pull one from the Store at all
  • The apt package is always a newer version than the matching Snap on the Store

An older AppImage fails to launch on Ubuntu 24.04 with a FUSE error. What is the correct fix?

  • Install libfuse2, since modern Ubuntu ships FUSE 3 while the AppImage links against FUSE 2
  • Re-download the file from the vendor, since a FUSE error reliably means the image was truncated or corrupted during the original download and a clean copy will run
  • Run the AppImage as root with sudo so it gains the privilege to mount its own bundled filesystem past the FUSE restriction
  • Convert the AppImage into a .deb with a repackaging tool first so dpkg installs it natively and sidesteps the FUSE layer entirely

You got correct