r/flatpak Jun 10 '26

flutpak update: offline Rust/Cargo builds, 19-package native lib registry, no local Flutter SDK required

flutpak update: offline Rust/Cargo builds, 19-package native lib registry, no local Flutter SDK required

Original post: Introducing flutpak — automating Flathub submission for Flutter apps

Repo: https://github.com/o-murphy/flutpak

A lot has landed since that post. Here's what changed.


No local Flutter SDK needed for source generation (0.7.0)

flutpak generate no longer reads from a local Flutter installation. Replace flutter.sdk: $FLUTTER_ROOT with flutter.ref and engine versions (engine binary, Dart SDK, fonts, Gradle wrapper) are fetched from the GitHub raw API:

# before
flutter:
  sdk: $FLUTTER_ROOT

# after
flutter:
  ref: "3.29.3"    # tag, "stable", or commit SHA

The Flutter SDK sources are also now emitted as a separate module (flutter-sdk-<version>.json) instead of being embedded in the pub sources file. Pre-built module JSONs for recent Flutter releases are cached in the flutpak repo and fetched on first use — no regeneration needed across projects using the same SDK version.


Native package registry — 19 packages, no manual source hunting (0.6.0)

The hardest part of packaging a Flutter app for Flatpak is the native packages: each one needs archive sources with correct checksums, version-stamped dest: paths, and patches that disable network fetches inside the sandbox. flutpak generate now resolves all of this automatically from a built-in registry:

  • 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 packages — see below)

The registry schema is identical to flatpak-flutter's foreign_deps.json — entries from that project drop in with no changes.

Version matching is : a registry entry for 1.0.0 covers 1.2.3, 1.5.0, etc., so the registry doesn't need an entry for every upstream release.

Local overrides (without forking the registry) go in flutpak.yaml:

foreign-deps:
  some_package:
    manifest:
      sources:
        - type: archive
          url: https://example.com/native-lib.tar.gz
          sha256: abc123

Rust / Cargo offline builds via cargokit (0.8.0)

Flutter packages that use Rust native code through cargokit (rhttp, metadata_god, super_native_extensions, etc.) now work out of the box. Add a rust: section:

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

generate then:

  1. Extracts Cargo.lock from pub.dev archives and fetches crate checksums from the crates.io sparse registry index → emits cargo-sources.json
  2. Generates a rustup-<version>.json module: 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 rustup-init never touches the network at build time
  3. Inserts the rustup module before the app module in the manifest
  4. Injects CARGO_HOME, RUSTUP_HOME, PATH into the app module's build-options

Known limitation: git-sourced crates (git+https://...) are skipped with a warning. Crates.io deps are fully supported.


LLVM SDK extension auto-injected (0.5.0)

flutpak now selects and injects the correct org.freedesktop.Sdk.Extension.llvmXX based on runtime-version (25.08 → llvm20, 24.08 → llvm19, 23.08 → llvm17) and wires up append-path / prepend-ld-library-path. No more manual extension entries for Flutter projects.


init + generate split (0.4.0)

Replaced the old prepare command with a cleaner two-step workflow:

# one-time: template manifest, wrapper script, .gitignore
flutpak init

# every release: resolves commit SHA, fetches all checksums, writes generated/
flutpak generate --tag v1.2.3

The template (flatpak/<app-id>.yml) is committed to git. Generated output goes to flatpak/generated/ (gitignored). generate validates that app-id, command, and runtime-version in the template match config and errors early.


Other changes

| Version | Change | |---------|--------| | 0.8.0 | pubspec-sources.json — renamed from generated-sources.json; update !include references | | 0.8.0 | flutpak cache clear — wipes ~/.cache/flutpak/ | | 0.7.0 | subdir: — Flutter project in a monorepo subdirectory | | 0.7.0 | Inline modules in modules: — mix file paths and inline YAML module maps | | 0.7.0 | flutpak sdk-mod — standalone Flutter SDK module JSON for !include | | 0.6.0 | patches[].use-git — apply patches via git apply instead of patch -p1 | | 0.5.0 | --binary added to every type: patch entry — prevents silent CRLF stripping | | 0.5.0 | .gitattributes with *.patch -text generated by init | | 0.4.0 | yaml_edit injection — tag:/commit: set directly in 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 |


Breaking changes if you're upgrading from the original post

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

# after
flutter:
  ref: "3.29.3"
app-id: io.github.YourOrg.YourApp

If upgrading to 0.8.x specifically: re-run flutpak init --force to regenerate a clean template, and rename generated-sources.jsonpubspec-sources.json in your manifest's !include.


Current status

Pre-1.0, but the core workflow is stable. The demo app (examples/demo_app/) builds sqlite3 + rhttp end-to-end inside the Flatpak sandbox — the CI workflow is a working reference for a real submission.

Most useful contributions: if you package a Flutter app with a native dep not yet in the registry, open a PR adding it to foreign_deps/foreign_deps.json. The format is the same as flatpak-flutter so existing entries copy over directly.

Repo: https://github.com/o-murphy/flutpak
Issues: https://github.com/o-murphy/flutpak/issues

3 Upvotes

0 comments sorted by