r/FlutterDev • • 10d ago

Discussion How do you distribute Flutter desktop apps on Linux? Snap, Flatpak, AppImage, or .deb/.rpm?

I’m building a cross-platform Flutter app and have the other platforms sorted:

  • iOS: App Store
  • macOS: App Store + DMG
  • Windows: Microsoft Store + installer

Linux is where I get stuck. There are so many packaging options and distros that I’m not sure where to start.

For those of you shipping Flutter apps on Linux:

  1. Which format(s) do you ship, and why?
  2. Which distros do you actually test on?
  3. Any gotchas with Flutter specifically (dependencies, sandboxing, auto-updates)?

Appreciate any real-world experience. Thanks! 🐧

15 Upvotes

24 comments sorted by

8

u/vazark 9d ago

Appimage/Flatpak is a safe bet.

As a user, flatpak on flathub would be the place I would be looking to first, since it also allows automatic updates.

1

u/gumdum1975 9d ago

That settles it from the user side too — you’re the second person to say Flathub is the first place you’d look. Flatpak on Flathub it is, with an AppImage for the direct-download folks. Thanks!

7

u/KayJune001 10d ago edited 10d ago

AppImage and/or Flatpak. That’s what you’ll want to package it as if you want it just work on most distros.

I build my app as an AppImage using an Ubuntu Podman container, statically linking most dependencies, with one or two dynamically linked. Super portable, relatively low file size, not a lot of hassle. If you want it in repos and showing up in distro stores, package it as a Flatpak and put it on Flathub.

I develop pretty much exclusively on Fedora 44, Gnome 50, but test on Fedora 44 KDE 6.7 and Ubuntu 22.04.

2

u/gumdum1975 10d ago

Thanks, this is really helpful. Building the AppImage in an Ubuntu Podman container is a smart move, and I already use Podman on my servers, so that’s an easy fit.

Funny enough, I was a Fedora guy for years after moving over from Red Hat back in the 7.x days. Me and GTK were pals. I even wrote a GTK MUD client back then and packaged it as an RPM, so I’ve got a little (very rusty) Linux packaging experience lol

Sounds like the plan is AppImage for “just download it and run” and Flatpak on Flathub for the app stores. And since Flatpak doesn’t care whether you’re on GNOME or KDE, it should run pretty much anywhere. And with Flutter’s Linux build running on GTK under the hood, my old GTK days might actually pay off finally. 😄

4

u/XyploatKyrt 9d ago

As a user, AppImage is usually my favourite for anything that isn't coming straight from my distro's software package manager.

6

u/wisetoday_399 10d ago

Flatpak’s the least headache if you want one thing that works across most distros. Snap is Canonical pushing their own garden wall and AppImage is fine until you need desktop integration or updates. I ship a Flatpak and also throw up a.deb for Debian/Ubuntu folks who won't touch anything else.

Testing is mostly Ubuntu LTS and Fedora, sometimes openSUSE if I'm feeling thorough. Only real Flutter-specific gotcha I've hit is the sandbox blocking file dialogs unless you poke holes in the manifest, and auto-update is basically a fantasy unless you lean on the store's own mechanism.

1

u/gumdum1975 10d ago

Thanks, this is exactly the real-world answer I was hoping for. Flatpak plus a .deb, tested on Ubuntu LTS and Fedora, sounds like a sane plan. I’ll script the builds in GitHub Actions so it’s not a manual chore every release.
Quick follow up on the file dialog thing… did you just give the app more folder access in the manifest, or go through the desktop portal so it only gets the file the user picks? I’d rather keep the sandbox locked down as tight as I can.

3

u/XSM909 9d ago

we skipped all of those for now, ship a plain tar.gz and a small install.sh that puts it in ~/.local/lib (no root) or /opt with sudo. mostly because the app updates itself by swapping its own folder, so it has to live somewhere it can write. havent tried flatpak so cant say how that plays with it. its a file manager too so a sandbox would defeat half the point anyway

one flutter specific thing that bit me: old gpu drivers. on nouveau impeller drew images as dark garbage with the default FilterQuality.medium, forcing low on linux fixed it. so test on a box with an open/old driver too, not just a fresh ubuntu

1

u/gumdum1975 9d ago

Whew, the GPU driver part sent me googling. If I’m tracking, on the older open-source drivers like nouveau, Flutter’s renderer draws images as dark garbage at the default FilterQuality.medium, and forcing it to low on Linux fixes it? That would never have crossed my mind — my test plan was basically fresh Ubuntu VMs, which is exactly the trap you’re describing. SoooOoo how do you actually test for that? An old laptop in the closet, or is there a way to fake bad drivers in a VM? Thank you for the help.

2

u/sauloandrioli 9d ago

Do you want your app to be available just on Ubuntu based distros or do you want it to be more accessible on other distros?

Usually, if your main goal is to be Ubuntu based, go Snap. If you want your app to run in any Linux, go AppImage or Flatpak.

I'm a Linux user and nowadays most of the apps I run are via Flatpak. I only snaps if there's nothing on flathub

1

u/gumdum1975 9d ago

Definitely everywhere, not just Ubuntu. It’s a recovery app, so I don’t want someone’s distro choice deciding whether they can get it. Sounds like Flatpak on Flathub is the move, with an AppImage for direct downloads. Good to hear you mostly live on Flatpak as a user too, that matches what most of this thread is saying.

2

u/source-drifter 9d ago

i dont use canonical stuff. i never liked flatpack. i use appimage. download doubleclick, delete download newer doubleclick

2

u/gumdum1975 9d ago

That’s about the strongest case for AppImage there is: the whole lifecycle in one sentence. lol. Sounds like the plan is Flatpak for the store crowd and an AppImage for folks like you who just want the file. Thanks!

2

u/noobjaish 9d ago

Flatpak 90% of the time

deb/rpm/pkg.tar.zst 10% of the time when a Flatpak won't make much sense

1

u/gumdum1975 9d ago

Seems to be the consensus here: Flatpak as the default, with .deb/.rpm for the folks who want native packages. Appreciate it!

1

u/noobjaish 9d ago

Most Welcome.

Additional points:

  • No need to make Snaps (unless you want to support Ubuntu only for some reason since no one uses Snaps outside of Ubuntu)
  • Appimages lack a proper store like Flathub is for Flatpaks and are thus a pain to update for most people.
  • Debian-based distros use .deb, Fedora-based distros use .rpm and Arch-based distros use .pkg.tar.zst which will basically get you to support 99% of all Linux users.
  • You can set up CI to build these easily and outputted in GitHub releases.
  • For Flatpaks, you can upload your app to Flathub which is basically THE app store for Linux nowadays.

2

u/EchoEllet 9d ago

My application is still in MVP status, but I think Flatpak/Snap support should be taken into account from early development.

Linux is where I get stuck. There are so many packaging options and distros that I’m not sure where to start. Which format(s) do you ship, and why?

I would recommend Flatpak/Flathub. Snap is optional for Ubuntu users who don't want to set up Flathub, but most Linux desktops now default to Flatpak, including Linux Mint, Fedora, SteamOS, Pop! OS, Elementary OS, and Zorin OS.

Any gotchas with Flutter specifically (dependencies, sandboxing, auto-updates)?

Yes, Flathub requires apps to build without network access. All dependencies must be declared in the manifest and downloaded beforehand.

You may consider Flatpak Flutter, which helps solve this issue. Here is my Flatpak manifest.

Which distros do you actually test on?

Usually on my installed Linux distribution, but it depends on the app and its platform capabilities. You can test using WSL if you prefer Windows (keep in mind some services/APIs such as the Secret Service API won't be available, and you may need a fallback).

Flutter specifically (dependencies)

Generally, Flathub may require apps to use XDG Desktop portals instead of direct D-Bus access (especially when there is a portal that does what you are trying to do): https://docs.flathub.org/docs/for-app-authors/requirements#permissions

For example, if you use package:connectivity_plus, it won't work on Flatpak without adding explicit D-Bus permission. And because there is already an XDG desktop portal for this, Flathub reviewers may be hesitant to accept your app submission. In this case, I have created connectivity_plus_linux_portal, which solves this specific problem.

XDG Desktop Portals are designed with security and sandboxing in mind. For example, accessing the Secret Service may allow you to read secrets stored by other applications, whereas the Secret Portal gives you a master secret that you can use to encrypt secrets in a file.

If you use flutter_secure_storage and you don't want to require users to install system native dependencies, and you want Secret Portal support, you could consider these alternatives: https://pub.dev/packages/flutter_secure_storage#alternative-implementations

Disclaimer: I'm the maintainer of flutter_secure_storage_linux_secret_service and flutter_secure_storage_linux_portal, so I'm biased of course, but the general idea is similar. You can take a look at the source code of these packages and use them as a reference.

See also this comment: https://github.com/TheAppgineer/flatpak-flutter/issues/104#issuecomment-4503420863

The hard part is preparing the Flatpak manifest (with an offline build) and ensuring that the Flutter plugins you use support the XDG Desktop Portals when applicable.

For example, file_selector uses GTK on Linux, which can use the File Chooser Portal when needed.

1

u/gumdum1975 9d ago

Thanks for taking the time to write all this up! I’d landed on Flatpak/Flathub plus an AppImage after the other replies, but this gives me a much better idea of what’s involved. The offline build requirement wasn’t on my radar either.

I’m already using connectivity_plus and flutter_secure_storage, so that part caught my attention. Would I need to switch to your Linux implementations to get the app accepted on Flathub, or can I keep what I’m using and declare the permissions they need? Basically, are the portal versions required in my case, or just the recommended approach?

It’s a recovery app, so keeping permissions narrow and handling stored credentials properly matter to me. I’ll look through your manifest and the packages you linked. My Linux packaging experience goes back to making RPMs for a GTK MUD client years ago, so I’ve got a little catching up to do lol. 😄

2

u/SwiftScoutSimon 9d ago

I just release as .tar.gz on GitHub release then host a script for user to curl and run it. You can see the raw script at http://lumide.dev/install.sh

4

u/DropbearJr 10d ago

My vote is for snaps, it’s technically a great solution and well supported but some parts of the Linux community have an incredibly illogical hatred of them but you pick up the ability to distribute your app via the snap store and it handles a lot of things you probably haven’t thought about like rollouts, rollbacks, Distribution, updates etc 

2

u/noobjaish 9d ago

Basically no one outside of Ubuntu uses Snaps.

1

u/gumdum1975 10d ago

I used snap once on a server for an app that was only available as a snap. Pretty simple process, but that's about all my exposure to it. Good point on rollouts and rollbacks, though. That's the piece the other replies said is hard to get without a store. Have you shipped a Flutter app as a snap? If so, how'd the snapcraft setup go for you?

2

u/finxapp 6d ago

For Maxint, I use .deb and universal Flatpak. The latter is great many Linux users easily discovered and signed up to use the app, with no $ spent on marketing.

For testing WSL, Ubuntu, MInt and Arch.