External Publication
Visit Post

Introducing flutpak - automating Flathub submission for Flutter apps

Flathub Discourse [Unofficial] June 2, 2026
Source

Introducing flutpak - automating Flathub submission for Flutter apps

Repo: GitHub - o-murphy/flutpak: Automates Flatpak packaging and offline builds for Flutter apps from pubspec.yaml. · GitHub Version: 0.4.0-rc.2 (pre-1.0, breaking changes expected until stable)


The problem

Flathub requires every source to be declared upfront with a SHA-256 checksum - no network access at build time. For a typical Flutter project that means:

  • Every pub.dev dependency needs two source entries in generated-sources.json: an archive download and an inline hash file that pub get --offline looks for separately. Miss the hash file and the build fails even if the archive is present.
  • The Flutter SDK brings its own set of artifacts - engine binaries, Dart SDK, material fonts, Gradle wrapper - each with architecture-specific variants for x86_64 and aarch64, all requiring correct checksums at a specific engine revision.
  • Packages like objectbox_flutter_libs require patch sources whose dest: path embeds the exact package version (.pub-cache/hosted/pub.dev/objectbox_flutter_libs-5.3.1). Update the package and that path silently goes stale, producing a manifest that passes linting but breaks at build time.
  • The Flutter SDK bootstrap script (shared.sh) calls pub upgrade, which requires network. It needs to be patched to pub get --offline for every Flatpak build, every Flutter version.
  • None of the existing generator tooling (flatpak-pip-generator and its siblings) understands the Dart/Flutter ecosystem.

Doing all of this by hand for a non-trivial app means tracking hundreds of source entries, re-verifying checksums on every dependency bump, and re-hunting Flutter artifact URLs on every Flutter release. This is the main reason Flutter apps are underrepresented on Flathub - not lack of interest, but the sheer amount of manual work required just to get to the point where you can open a submission PR.


What flutpak targets

flutpak is not a general Flatpak build tool. It is specifically aimed at producing the output that a Flathub submission expects:

  • A generated-sources.json in the format Flathub reviewers are familiar with
  • A manifest that passes flatpak-builder-lint --exceptions without manual tweaks
  • A flathub.json with correct submission metadata
  • Metainfo and desktop entry validation via appstreamcli as part of the generate step
  • GitHub Actions that mirror the flathub-build pipeline used in Flathub CI, so what passes locally also passes in review

The goal is to reduce the gap between “my app builds with Flutter” and “my app is published on Flathub” to a config file and two commands.


Where flutpak started

The first version (0.1.0, May 2026) was a single prepare command that generated generated-sources.json from a lock file and patched a manifest using __FLATPAK_TAG__ / __FLATPAK_COMMIT__ placeholder strings. It also generated metainfo XML and .desktop files from config, and had lint, validate, and export wrapper commands around the official Flatpak toolchain.

It worked for one app. It was also immediately clear what was wrong with it:

  • The metainfo and desktop file generators were fragile and duplicated what appstreamcli and the Flathub submission process already validate. Removed in 0.2.8.
  • The lint and validate wrappers around official tools added complexity without value. Removed in 0.2.5-0.2.6.
  • Patch sources were baked into generated-sources.json at init time. The dest: path included the package version, so any version bump silently produced a broken manifest. Fixed in 0.4.0-beta.2 by moving patch injection to generate time, where the current pubspec.lock is always available.
  • The manifest template carried __FLATPAK_TAG__ and __FLATPAK_COMMIT__ strings that generate replaced with sed. Any YAML structural change near those strings risked breaking substitution. Replaced in 0.4.0-rc.1 with direct yaml_edit injection into the correct YAML node - no strings to maintain, no fragile text replacement.
  • Config keys were inconsistently cased (app_id, runtime_version, etc.) and mixed flutpak-specific fields with Flatpak manifest fields in the same section. Cleaned up in 0.4.0-rc.1: all keys are now kebab-case, and flutpak-specific fields (repo-url, metainfo-path, icons) live at the root level rather than inside manifest:.

The general direction has been: remove everything that duplicates official tooling, automate everything that is mechanical and error-prone, and keep the config minimal.


What it looks like now

Two commands cover the full workflow:

flutpak init - run once. Generates the editable template manifest, a Flutter wrapper shell script, flathub.json, and .gitignore. Validates that your metainfo, desktop entry, and icon files exist before writing anything.

flutpak generate --tag vX.Y.Z - run on every CI build. Reads the committed template, writes tag: and commit: directly into the git source block via yaml_edit, generates generated-sources.json, and copies everything to flatpak/generated/ ready for flatpak-builder.

The minimum config to get started:

# flutpak.yaml
flutter:
  sdk: $FLUTTER_ROOT
manifest:
  app-id: io.github.YourOrg.YourApp

Everything else - command name, repo URL, flutter version file path, sandbox permissions - is either auto-detected or written into the template on init with sensible defaults. You edit the template directly; flutpak never overwrites it.

The known-patches/ directory ships reference patch files and companion Flatpak module files for packages that commonly need offline build modifications. For example, objectbox_flutter_libs needs a CMakeLists.txt patch to use a prebuilt library instead of fetching it at build time. Copying the relevant files and adding two lines to config is enough - generate handles the rest, including the version-stamped dest: path and stripping CRLF line endings if the upstream archive has them.

GitHub Actions composite actions are provided for CI, mirroring the Flathub build pipeline:

- uses: o-murphy/flutpak/.github/actions/generate@v0.4.0-rc.2
  with:
    tag: ${{ github.ref_name }}
    metainfo-path: app/share/metainfo/<app-id>.metainfo.xml
- uses: o-murphy/flutpak/.github/actions/build-flatpak@v0.4.0-rc.2
  with:
    manifest: flatpak/generated/<app-id>.yml
    app-id: io.github.YourOrg.YourApp

Dogfooding

I am using flutpak to package ebalistyka for Flathub. The tool exists because I needed it and nothing else filled this gap. That submission is still in progress - which is exactly why the API is not stable yet. Working through a real Flathub submission is what surfaces the remaining rough edges.


Where community help matters most

known-patches/ is where the most useful community contributions can land. If you use a Flutter package that requires a patch source - pre-built native libraries, CMake modifications, anything that needs a type: patch or type: shell source in the manifest - contributing a patch file and companion module there makes it work automatically for everyone using that package.

Beyond patches:

  • Bug reports and edge cases from real apps are the most valuable feedback at this stage
  • Feedback on the manifest structure that flutpak init generates
  • Packages that require source handling not yet covered

Issue tracker: Issues · o-murphy/flutpak · GitHub


*Pre-1.0 means breaking changes are possible between minor versions. The changelog documents them. If you are packaging a Flutter app for Flathub - or have been putting it off because the source generation work seemed too painful

  • this is worth a look.*

Discussion in the ATmosphere

Loading comments...