External Publication
Visit Post

Introducing flutpak - automating Flathub submission for Flutter apps

Flathub Discourse [Unofficial] June 10, 2026
Source

flutpak — major update (0.8.0): Rust/Cargo support, flatpak-flutter-compatible registry, no local SDK required

Since the original post (and the first successful Flathub CI run) a lot has landed. I want to give a proper update, especially on two points raised in the thread.

A note on the proof-of-concept submission

The previous update in this thread reported that PR #8889 passed the Flathub test build on the first try — that part is still true: the build succeeded for both x86_64 and aarch64. However, the PR was subsequently closed for reasons unrelated to the packaging itself:

  1. Proprietary dependencyobjectbox-c is distributed as a prebuilt binary under the Apache License with no source code available. @hfiguiere flagged this as incompatible with the app’s GPL-3.0 license.
  2. Generative AI policy — Flathub’s requirements restrict AI-generated code in submissions. Claude was used during development of the app, which made the PR ineligible.

Neither of these is a flutpak issue — the tool produced a correct, buildable manifest. The rejection is about the specific app’s dependencies and its codebase, not the packaging toolchain. I mention it for transparency since this thread had the earlier “CI passed” update and it would be misleading to leave it without follow-up.


Registry now compatible with flatpak-flutter

@bbhtt raised the point about flatpak-flutter. Since then the foreign deps registry format has been aligned to be fully schema-compatible withflatpak-flutter’s foreign_deps.json. Every entry from the flatpak-flutter registry can be used in flutpak with no changes. flutpak extends the schema by one optional field (crlf: on patch sources); flatpak-flutter silently ignores it.

The registry currently covers 19 packages:

  • objectbox_flutter_libs / objectbox_sync_flutter_libs
  • sqlite3 / sqlite3_flutter_libs / sqlcipher_flutter_libs
  • simple_secure_storage_linux
  • audiotags, flutter_webrtc, media_kit_libs_linux, pdfium_flutter, printing, flutter_new_pipe_extractor, fvp, powersync
  • rhttp, metadata_god, super_native_extensions, flutter_discord_rpc, flutter_vodozemac (cargokit/Rust — see below)

All native archive sources, patches, and version-stamped dest: paths are resolved and injected automatically by flutpak generate. No manual source hunting per release.

Version matching is: a registry entry for 1.0.0 covers 1.2.3, 1.5.0, etc., reducing churn when upstream bumps patch/minor versions.


Rust / Cargo offline builds (0.8.0)

Flutter plugins using cargokit (rhttp, metadata_god, super_native_extensions, etc.) now work out of the box. Add a rust: section to flutpak.yaml:

rust:
  version: 1.85.0
  rustup-path: /var/lib/rustup

generate will:

  1. Extract Cargo.lock from pub.dev archives, fetch SHA-256 checksums from the crates.io sparse registry index, emit cargo-sources.json
  2. Generate rustup-<version>.json: downloads the channel manifest, rustup-init binaries, and a minimal toolchain (rustc, cargo, rust-std) for both x86_64 and aarch64; sets RUSTUP_DIST_SERVER to the pre-downloaded static directory so nothing touches the network at build time
  3. Insert the rustup module before the app module in the generated manifest
  4. Wire CARGO_HOME, RUSTUP_HOME, and PATH into the app module’s build-options

Known limitation: git-sourced crates (git+https://...) are skipped with a warning — they require cloning at generate time, which is out of scope. Crates.io dependencies are fully supported.


No local Flutter SDK required for generate (0.7.0)

flutpak generate no longer reads from a local Flutter installation. Engine versions (engine binary, Dart SDK, fonts, Gradle wrapper checksums) are fetched from the GitHub raw API using flutter.ref:

flutter:
  ref: "3.44.1" # tag, branch, or commit SHA

The Flutter SDK sources are emitted as a standalone module (flutter-sdk-<version>.json) — separate from pubspec-sources.json. Pre-built module JSONs for recent Flutter releases are cached in the flutpak repo and fetched on first use, avoiding regeneration across multiple projects on the same SDK version.


LLVM SDK extension auto-injected (0.5.0)

The correct org.freedesktop.Sdk.Extension.llvmXX is now selected automatically based on runtime-version (25.08 → llvm20, 24.08 → llvm19, 23.08 → llvm17) with append-path / prepend-ld-library-path wired up. No manual extension entry needed.


Breaking changes since the original post

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

# after (0.8.0)
flutter:
ref: "3.29.3"
app-id: io.github.YourOrg.YourApp
  • generated-sources.json → renamed to pubspec-sources.json (update !include references)
  • Flutter SDK sources moved out of pubspec-sources.json into a separate module
  • Re-run flutpak init --force after upgrading to 0.8.x to get a clean template

Other notable changes

Version Change
0.8.0 flutpak cache clear — wipes ~/.cache/flutpak/
0.7.0 subdir: — Flutter project in a monorepo subdirectory
0.7.0 flutpak sdk-mod — standalone Flutter SDK module JSON for !include
0.6.0 patches[].use-gitgit apply instead of patch -p1
0.5.0 --binary on every type: patch entry — deterministic CRLF handling
0.5.0 .gitattributes with *.patch -text generated by init
0.4.0 yaml_edit injection — tag:/commit: written directly into the git source block
0.4.0 actions/generate + actions/build-flatpak composite CI actions
0.4.0 Retry on 429/5xx for all network fetches

Current status

The core workflow is stable. The demo app (examples/demo_app/) builds sqlite3 + rhttp end-to-end inside the Flatpak sandbox on both architectures — the CI workflow is a working reference. The most impactful contribution right now: if you maintain or package a Flutter app with a native dep not yet in the registry, a PR adding it to foreign_deps/foreign_deps.json makes it work for everyone. The format is identical to flatpak-flutter, so existing entries can be copied directly.

Discussion in the ATmosphere

Loading comments...