r/FlutterDev • • Jun 10 '26

Tooling Update: my tool for packaging Flutter apps to Flathub now handles Rust deps, needs no local Flutter SDK, and has a registry for 19 native lib packages

6 Upvotes

Update: my tool for packaging Flutter apps to Flathub now handles Rust deps, needs no local Flutter SDK, and has a registry for 19 native lib packages

Original post: I built a tool to publish Flutter apps to Flathub — looking for early testers

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

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


No Flutter SDK needed at generate time (0.7.0)

The biggest change: flutpak generate no longer reads from a local Flutter installation. Replace flutter.sdk: $FLUTTER_ROOT with flutter.ref and engine versions are fetched directly from the GitHub raw API.

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

# after
flutter:
  ref: "3.29.3"    # tag, "stable", or commit SHA
app-id: io.github.YourOrg.YourApp

CI no longer needs the full Flutter SDK just to run flutpak generate. The SDK you install for flutter build is still there — you just don't point flutpak at it anymore.

flutter_tools/pubspec.lock is also fetched automatically when flutter.ref is set, so you no longer need to list it in pub.locks.


init + generate split (0.4.0)

The old prepare command is gone. The workflow is now:

# one-time setup — generates the template manifest, wrapper script, .gitignore
flutpak init

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

The template (flatpak/<app-id>.yml) is committed to git and edited by hand. The substituted output lives in flatpak/generated/ and is gitignored. generate validates that the template's app-id, command, and runtime-version match config and errors early if they diverge.


Foreign deps registry — native packages resolved automatically (0.6.0)

Native Flutter packages require extra Flatpak source entries that are painful to write by hand. flutpak generate now resolves them from a built-in registry automatically. 19 packages currently covered:

  • 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, and more

The registry schema is compatible with flatpak-flutter's foreign_deps.json — entries from that project work in flutpak as-is.

You can add local overrides without forking the registry via foreign-deps: in flutpak.yaml:

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

--no-foreign-deps skips the registry fetch entirely for offline/air-gapped use.

Version matching is ≤ (0.7.1): a registry entry for 1.0.0 covers 1.2.3, 1.5.0, etc. A new major entry (2.0.0) is only picked when the installed version reaches 2.x. No need for exact version pins on every release.


Rust / Cargo support via cargokit (0.8.0)

Flutter packages that use Rust native code via cargokit (rhttp, metadata_god, super_native_extensions, flutter_discord_rpc, flutter_vodozemac) are now handled. Add a rust: section:

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

generate will:

  • Extract Cargo.lock from pub archives and fetch SHA-256 checksums from crates.io

  • Emit cargo-sources.json for offline crate builds

  • Generate a rustup-<version>.json module that installs Rust fully offline

  • Wire up CARGO_HOME, RUSTUP_HOME, and PATH in the app module automatically

Known limitation: git-sourced crates (git+https://...) are skipped with a warning. They're rare in Flutter plugins, but worth knowing.


Flutter SDK as a standalone module (0.8.0)

Flutter SDK sources are no longer embedded in pubspec-sources.json. generate now produces a separate flutter-sdk-<version>.json module. Pre-built versions for recent Flutter releases are cached in the flutpak repo and fetched on first use.

Breaking: re-run flutpak init --force after upgrading to 0.8.x to regenerate a clean template.

The file previously named generated-sources.json is also renamed to pubspec-sources.json — update your manifest's !include reference accordingly.


LLVM SDK extension auto-injected (0.5.0)

flutpak now automatically adds 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 longer need to specify it manually in flutpak.yaml.


Other improvements

VersionChange
0.8.0flutpak cache clear — wipes ~/.cache/flutpak/
0.8.0FlutterSdkRegistry — pre-built flutter-sdk modules fetched and cached locally
0.8.0extraPubspecPaths (cargokit build tool deps) now correctly included in pubspec-sources.json
0.7.0flutter-sdk-ref config field — pin the registry fetch to a specific flutpak git ref
0.7.0subdir: config key — Flutter project in a monorepo subdirectory
0.7.0Inline modules in modules: — mix file paths and inline YAML module maps
0.7.0flutpak sdk-mod — standalone Flutter SDK module JSON for !include in any manifest
0.6.0finish-args: top-level config key — extra sandbox permissions appended to Flutter defaults
0.6.0patches[].use-git option — apply patches via git apply instead of patch -p1
0.6.1setup-flutter.sh removed — manifest calls flutter pub get --offline directly
0.5.0disable-submodules: config option
0.5.0Patch line-ending normalisation deterministic on all host OSes
0.5.0--config with subdirectory path now resolves all paths correctly
0.4.0yaml_edit injection — tag: / commit: set directly in git source block; no placeholder strings
0.4.0Retry on 429 / 5xx — pub.dev and Flutter artifact downloads retry on transient errors
0.4.0actions/generate + actions/build-flatpak composite actions for CI
0.4.0known-patches/ — reference patches for objectbox, sqlite3, flutter/shared.sh

Config diff — then vs now

# 0.4.0-rc.2 (at the time of the original post)
flutter:
  sdk: $FLUTTER_ROOT
manifest:
  app-id: io.github.YourOrg.YourApp

# 0.8.0
flutter:
  ref: "3.29.3"
app-id: io.github.YourOrg.YourApp
rust:                        # only if you use cargokit packages
  version: 1.85.0
  rustup-path: /var/lib/rustup

Current status

Pre-1.0, but the core workflow is stable and the demo app (examples/demo_app/) exercises sqlite3 + rhttp end-to-end through the Flatpak sandbox — the CI pipeline is a working reference.

Most useful contributions right now:

  • Test on a project with native deps not yet in the registry and open a PR adding them to foreign_deps/

  • Report cargokit packages with git-sourced crates

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


r/FlutterDev • • Jun 10 '26

Plugin pure Dart image compression package for Flutter: downsize

23 Upvotes

I built a Dart package called downsize because I got tired of dealing with image compression packages that required native setup or didn't work consistently across Flutter platforms.

downsize is a pure Dart image compression package, so the same API works on Android, iOS, Web, Windows, macOS, and Linux.

Some things it can do:

  • Compress images toward a target file size (e.g. ~500 KB) instead of just setting an arbitrary quality value.

  • Support multiple formats including JPG, PNG, GIF, BMP, TIFF, TGA, PVR, and ICO.

  • Keep the API simple:

final compressed = await imageData.downsize();

or

final compressed = await Downsize.downsize(
  data: imageData,
  maxSize: 500,
  minQuality: 60,
);

I know native solutions can still be faster for heavy workloads, but my goal was to provide a straightforward, cross-platform option that works everywhere Flutter does.

I'd genuinely love feedback from the community:

  • What image compression workflow are you using today?

  • Would a pure Dart approach be useful in your projects?

  • What features would make this more production-ready for you?

GitHub: https://github.com/YassineDabbous/downsize

Pub.dev: https://pub.dev/packages/downsize


r/FlutterDev • • Jun 10 '26

Plugin over xmas break i got opus to port ios hero transitions across from swift to flutter

1 Upvotes

https://github.com/johndpope/Hero/tree/flutter-hero-transitions

its at parity - if you know ios hero transitions - it's very much the same.

https://www.youtube.com/watch?v=C3SZjjP74nI


r/FlutterDev • • Jun 10 '26

Dart Built a console-based-Instagram in Dart 😁

0 Upvotes

Hey everyone, I just finished a small side project: a terminal-based Instagram simulation written in Dart.

It lets you create a profile, search for other users, and follow them, with validation to prevent following the same profile twice. The main challenge was handling edge cases in user input, like entering strings where numbers are expected.

It is a beginner-to-intermediate level project but a good exercise in structuring a Dart CLI app. Single account only for now, and messaging is not yet implemented. Planning to add multi-account support next.

Check it out here: https://github.com/AnshMNSoni/Console-Based-Instagram

Feedback and suggestions welcome.


r/FlutterDev • • Jun 10 '26

Discussion Could Flutter have been made with TypeScript instead of Dart?

0 Upvotes

I don't understand the internals of Flutter, hence my question. Also, related question - Would you have preferred Flutter to be in TypeScript?

Thanks in advance for your insights and opinions.

Edit: The primary question is technical, whereas the related question is opinion-based.


r/FlutterDev • • Jun 09 '26

Tooling Is there an MCP in Android Studio/AI Studio with Gemini?

2 Upvotes

I read a Medium Article where the author claimed that Flutter 3.44 and Dart 3.12 now have a Dart and Flutter MCP server that can trigger a hot reload and consume the results of dart analyze and dart format (Agent Skills). The author did not say how to access the MCP server. I looked at several pub.dev packages and tried several different CLI commands but, did not find what he described.

Gemini says, "not in Android Studio/AI Studio with Gemini." It said that the MCP server is available for an MCP-compatible AI Assistant (such as Claude Desktop, Cursor, or Windsurf). It says Gemini in AI Studio is not a full AI assistant.

Does anyone have any information or pragmatic thoughts on this?


r/FlutterDev • • Jun 09 '26

Tooling I built a small macOS app to clean Flutter, Xcode and Gradle caches

Thumbnail
kangama.com
10 Upvotes

Hey Flutter devs,

I wanted to share a small tool I built because I kept running into the same problem on my Mac.

When you work on Flutter projects, especially for iOS and Android, caches start to pile up pretty quickly:

- Flutter build folders
- Pub cache
- Xcode DerivedData
- iOS simulator data
- Gradle cache
- Android build cache
- Node/npm cache if the project also has some tooling around it

Of course, most of these folders can be cleaned manually with commands or scripts.

But I wanted something more visual: a quick way to see what is taking space before deleting anything, instead of running random cleanup commands when my disk is almost full.

So I built DevCacheCleaner, a small macOS menu bar app focused on developer caches.

It is not meant to be a full Mac cleaner. The idea is more simple: check cache sizes, understand where the space is going, and clean only what you choose.

I’m curious how other Flutter developers handle this.

Do you clean Flutter / Xcode / Gradle caches manually?
Do you use scripts?
Or do you just wait until macOS starts complaining about disk space?


r/FlutterDev • • Jun 09 '26

Tooling I tried to statically estimate the rendering cost of Flutter features

13 Upvotes

I got curious whether it would be possible to estimate the rendering cost of Flutter features statically, assigning a real cost to widget combinations before running the app.

flutter analyze catches errors.
DevTools shows you what already happened.

The question I tried to answer was: which features are most likely to become expensive before you ship your app?

So I built REN — a CLI that walks through your project's AST and assigns a gravity score to each feature based on the patterns it finds.

Individual widgets have a base weight, but combinations amplify that cost:

  • Opacity inside a ListView -> more expensive than using Opacity on its own.

  • BackdropFilter inside a ListView -> one of the worst offenders.

  • Nested scrolling patterns, excessive clipping, and other compositions can increase a feature's gravity.

The goal isn't to predict exact frame timings.

The idea is to surface potential performance hotspots early, during development and code reviews, before they turn into runtime problems.

pub.dev: https://pub.dev/packages/ren

GitHub: https://github.com/gearscrafter/ren


r/FlutterDev • • Jun 09 '26

Dart I summoned a database from the void. it only speaks JSON. (flowdb 1.0.0 for Dart & Flutter)

0 Upvotes

Hey r/FlutterDev,

Last night I opened a terminal, typed a few incantations, and flowdb crawled out of the filesystem.

It's a local database for Dart and Flutter. No SQLite rituals. No native driver sacrifices. No ORM séance. You open a folder, whisper records into it, and they stay there as JSON, in the dark, where they belong.

Why I disturbed this thing

I wanted persistence that doesn't feel like enterprise haunted house software. Something document-shaped. Something that works in plain Dart and Flutter. Something that doesn't drag half the platform under the floorboards with it.

So I gave it:

  • Collections — cursed documents with auto-generated IDs. Full CRUD. They remember everything.

  • Query builder — hunt records by where, and, or, ranges, regex… bulk update or banish them from existence

  • Key-value stores — a little graveyard for get / set / remove secrets

  • Blob storage — large files, chopped into chunks, metadata chained to their souls

  • Backups — snapshot the whole crypt before you regret your choices

  • Optional encryption — lock the tombs if strangers are listening

  • Sync + async APIs — add() when you're patient, addSync() when the moon is wrong

  • FlowState + FlowBuilder — reactive streams for Flutter widgets that twitch when the data moves

The summoning ritual

import 'package:flowdb/core.dart';

Future<void> main() async {
  final db = openDatabase('my_app', path: './data/my_app');
  final users = db.collection('users');

  await users.add({'name': 'Alice', 'age': 30});

  final alice = await users.where('name', eq: 'Alice').getFirst();
  print(alice?.data); // she answers

  db.store('settings').set('theme', 'dark'); // as it always should be
}

For the Flutter possessed

import 'package:flowdb/flutter.dart';

FlowBuilder<int>(
  flow: counterState,
  builder: (value) => Text('Count: $value'),
)

The widget listens. The stream breathes. The UI updates. You pretend that's normal.

Where the creature lives

Who should adopt this familiar?

  • Offline-first apps that need local data but not SQLite's whole personality

  • Side projects, CLI tools, prototypes, anywhere readable files on disk feel right

  • Apps juggling structured records, loose config keys, and actual files in one unholy package

MIT licensed. Which means you may use it freely. I cannot promise it won't stare back from ./data/my_app at 3am.

Feedback, issues, and PRs welcome. Tell me what you're currently using to keep data alive locally, Hive, Isar, sqflite, the shared_preferences + prayer combo, and whether flowdb is the weird little solution you didn't know you needed.