r/FlutterDev 6h ago

Discussion Boss wants to switch our 100K+ user native apps to Flutter for "3x faster" delivery — am I actually biased, or is this a bad call?

50 Upvotes

ong-time mobile/product lead here. Looking for outside perspective because I'm now questioning myself after a long argument with my boss.
Context: I work on external client apps as well as our main customer portal app — the one used by the majority of our customer base. Our mobile apps are native, built about 6 years ago:
Android: Java/Kotlin + XML
iOS: Swift + UIKit
Web: React

100K+ users. Zero limitations adding features or maintaining these apps over the years. Apps are feature rich and AI based new features are in plan for revamp.

What's happening: We have a full revamp of the apps and portal coming up, and we're updating our tech stack too. My plan:
Android → Kotlin + Compose
iOS → SwiftUI
Web → Next.js
I already have multiple Android, iOS, and web devs trained on this stack.

The conflict: My boss wants to consolidate to Flutter — one team, one codebase, covering web/Android/iOS. His argument: if I put 6 frontend devs on one Flutter codebase instead of splitting across native platforms, we ship 3x faster.

My pushback:
We have zero Flutter training on the team right now
Native apps perform better and feel more premium
We have built Flutter apps before, but only for external client projects, not our own flagship product
He thinks I'm biased toward native because it's my background. Might be some truth to that, but I don't think that's the whole story.

Anyone actually shipped a migration like this — native to Flutter, or vice versa, at similar scale? Did the "one codebase, ship faster" promise hold up? Would love real-world experience, not theory.


r/FlutterDev 5h ago

Article Code injection via .arb translation files in flutter gen-l10n; check your CI and automated translation pipeline

Thumbnail
badranh1.medium.com
14 Upvotes

I just discovered an issue in Flutter that may compromise your app: you can literally write Dart code in your translation files and have it execute in production.

flutter gen-l10n validates ARB resource names but not the placeholder type field, which gets dropped straight into generated Dart. A crafted type string injects arbitrary code that compiles clean and runs when the localization is called.

Not a big deal if your .arb changes get reviewed like code, but plenty of teams auto-merge translations from CI or a third-party tool with nobody reading them, and that's where it gets dangerous: a hacked translation account, a malicious translator, or a compromised vendor can inject code into .arb files that runs in your production app.

It's rare, but it can easily turn into a supply chain attack.

for example:

{
  "@@locale": "en",
  "greeting": "Hello {user}",
  "@greeting": {
    "placeholders": {
      "user": {
        "type": "Object user) { print('>>> ARBITRARY DART EXECUTED FROM A TRANSLATION FILE <<<'); return 'pwned'; } String injectedByTranslation(Object"
      }
    }
  }
}

The print will be executed normally.

Full explanation: https://badranh1.medium.com/a-translation-file-can-hack-your-flutter-app-google-says-thats-not-a-vulnerability-ae175473acd3

EDIT: The issue is reported to Google, but it was closed without a fix as they believe it poses no security risk, that is why I am posting it publicly, a nice to know.


r/FlutterDev 5h ago

Dart Building a bit-perfect FLAC audio player using Flutter and Zig

4 Upvotes

Hey r/FlutterDev,

I wanted to share a project I’ve been working on called Listener (Link:https://github.com/johnngugi/listener).

It’s a custom bit-perfect audio player and streaming app. The goal was to send uncompressed FLAC PCM data directly to external DACs without the operating system interfering.

Most standard Flutter audio plugins route everything through the OS mixer, which inevitably resamples the audio. To get true bit-perfect playback, I needed to bypass the mixer entirely and talk directly to the native audio APIs (WASAPI on Windows, CoreAudio on macOS).

Here is how I set up the stack:

  • The Audio Engine (Zig): Zig does all the heavy lifting. It decodes the FLAC files, manages a custom TCP network protocol for streaming, and pushes the audio buffers directly to the DAC using the native OS APIs.
  • The Bridge (Dart FFI): Dart acts strictly as a control plane and never actually touches the audio buffers. Flutter simply sends commands (play, pause, seek, load) down to Zig via FFI. Keeping the buffers entirely within Zig ensures that Dart's garbage collection or UI thread overhead can never cause stutters in the audio stream.
  • The Frontend (Flutter): The user interface is currently very barebones and needs a lot of work. The core focus so far has been getting the native audio pipeline rock solid.

I’m sharing this because bridging Flutter with a low-level systems language like Zig for high-performance audio isn't a super common use case, and I thought this control-plane architecture might be interesting to share.

I’d love any feedback on the FFI implementation or how I'm handling the native API integrations. Also, if anyone is passionate about audio UI and wants to critique (or help improve) the frontend, I'm all ears.


r/FlutterDev 18h ago

Plugin Same Flutter code renders real iOS 26 Liquid Glass and Material 3 Expressive — depending on what OS it's running on

Thumbnail
github.com
25 Upvotes

r/FlutterDev 3h ago

Discussion Used a bitmask instead of a list<bool> for calendar slot availability — here's why

1 Upvotes

I built the scheduling engine for a driving-school app (students book lessons with instructors, pay with Stripe 3DS) and ended up modeling day availability as a single int bitmask instead of a List<bool> per day. Each bit = one 30-min slot, and merging "instructor's recurring template minus existing bookings minus days off" collapses into a couple of bitwise & / ~ ops instead of nested loops — which mattered once I had to merge two separate availability sources (regular bookings + a bonus "extra sessions" feature) without double-counting overlapping slots.

Also hit the classic timezone bug: comparing slot keys as date strings across a day boundary meant a slot generated in the instructor's local time landed on a different calendar date than the same instant in the student's timezone, so dedup silently failed. Fixed by keeping everything in UTC internally and only converting to local time at the very last render step.

Wrote up the full thing with code samples here: https://www.mostafijur-rahman.com/blog/bitmask-calendar-scheduling-flutter.html

Curious if anyone else has dealt with merging multiple availability sources like this, or found a cleaner pattern than bitmasking for slot-based scheduling in Dart.


r/FlutterDev 3h ago

Discussion Used a bitmask instead of a list<bool> for calendar slot availability — here's why

1 Upvotes

I built the scheduling engine for a driving-school app (students book lessons with instructors, pay with Stripe 3DS) and ended up modeling day availability as a single int bitmask instead of a List<bool> per day. Each bit = one 30-min slot, and merging "instructor's recurring template minus existing bookings minus days off" collapses into a couple of bitwise & / ~ ops instead of nested loops — which mattered once I had to merge two separate availability sources (regular bookings + a bonus "extra sessions" feature) without double-counting overlapping slots.

Also hit the classic timezone bug: comparing slot keys as date strings across a day boundary meant a slot generated in the instructor's local time landed on a different calendar date than the same instant in the student's timezone, so dedup silently failed. Fixed by keeping everything in UTC internally and only converting to local time at the very last render step.

Wrote up the full thing with code samples here: https://www.mostafijur-rahman.com/blog/bitmask-calendar-scheduling-flutter.html

Curious if anyone else has dealt with merging multiple availability sources like this, or found a cleaner pattern than bitmasking for slot-based scheduling in Dart.


r/FlutterDev 13h ago

Tooling Announcing Appwrite 2.0: Rewrite in TanStack, Postgres included and more

Thumbnail
6 Upvotes

r/FlutterDev 5h ago

Tooling I made an open-source DJ app with Flutter

Thumbnail
github.com
1 Upvotes

I made a free open-source Flutter Android-only (for now) DJ app. I was tired of all the DJ apps that charge you a monthly fee for something you should be able to own.

Github: https://github.com/manueljpy/SideDeck

And for the r/selfhosted nerds, this app lets you connect to your own Subsonic music server to search and download songs on you device.


r/FlutterDev 8h ago

Tooling scroll to index, on scroll direction changed, start at end, and scroll physics now native in FlutterFlow's ListView

Thumbnail
youtu.be
1 Upvotes

if you've been building scroll behavior in Flutter, you'll recognize these.

scroll to index: pick a ListView and an index, choose animate or jump. zero indexed, so 0 is the top. animated moves take a duration.

on scroll end: fires when the list reaches the bottom. use it to load the next batch of posts and keep queries small.

on scroll start: fires when the list reaches the top. use it to animate a collapsible header back into view.

on scroll direction changed: fires when the user reverses direction. exposes toward start or toward end so you can branch on it.

scroll physics: controls how the list feels when you drag and release, or whether it scrolls at all.

start at end: opens already scrolled to the bottom. item order doesn't change. use it for logs, transaction history, activity feeds.

scroll offset and max scroll extent: two new readable properties. how far you've scrolled from the beginning and the maximum the list can scroll.


r/FlutterDev 15h ago

Plugin ACT Dart Tools: a deterministic CLI to migrate entire Dart codebases to the new primary constructors syntax

Thumbnail
github.com
2 Upvotes

r/FlutterDev 14h ago

Dart Read Dart documentation offline with dart_offline_documentation

Thumbnail
1 Upvotes

r/FlutterDev 8h ago

Video Null Safety in dart

0 Upvotes

Have you ever encountered the dreaded "Null Check Operator" error in your Flutter application?

In this video, I'll show you how to use Null Safety to write more robust, secure code free of unexpected errors.

🔗Watch the full video here

https://youtu.be/KmDsTQigCfw

#coding #programming #Flutter #Dart #Programming #Dev


r/FlutterDev 1d ago

Discussion Local-first with Drift + optional sync: keeping phone DB as source of truth

8 Upvotes

Hey been shipping a Flutter app local-first for a while

Drift is the source of truth on device, works fully offline, cloud sync is optional and just sits on top. So far I'm sticking with phone DB as the real source of truth even after sync exists, server is more of a backup/sync layer than the boss

Offline edits then sync coming back later is still the messy bit. I've been keeping conflict UX intentionally dumb instead of building a merge engine, that tradeoff has been fine for this product so far

Stack is Cubit + Freezed + optional Firebase. Curious if other folks building local-first ended up the same way or flipped to server-as-canonical later


r/FlutterDev 1d ago

Article Flutter Desktop in Production: How We Test ASO.dev’s UI with Golden Tests

Thumbnail
aso.dev
12 Upvotes

r/FlutterDev 1d ago

Plugin I built an Adaptive Image Picker for Flutter: Zero-permission PhotoPicker + Pure-Dart Cropping & Binary Search Compression

34 Upvotes

Hey Flutter community! 👋

In almost every production Flutter app, handling image picking usually requires stringing together 2–3 different packages (image_pickerimage_cropper, and a compression plugin), managing invasive storage permissions on Android/iOS, and dealing with native build issues (like UCrop pod conflicts on iOS/Android).

To solve this, I built adaptive_image_picker — a lightweight, unified, zero-permission media pipeline.

✨ Key Features:

  • 🔒 Zero Permissions by Default: Native integration with Android 13+ Photo Picker (PickVisualMedia) and iOS 14+ PHPickerViewController. No READ_EXTERNAL_STORAGE needed.
  • ✂️ Pure-Dart Cropper: No native UI wrappers (like UCrop). Supports freeform cropping, aspect ratio presets, 90° rotation, horizontal/vertical flipping, and antialiased circular avatar masking.
  • ⚡ Binary Search Target-Size Compression: Automatically compresses images to guarantee a file size ≤≤ maxBytes (e.g. max 500 KB) without manual guessing.
  • 🎨 Adaptive Native UI: Automatically renders Material 3 bottom sheets on Android, Cupertino action sheets on iOS, and modal dialogs on Web/Desktop.
  • 🌐 Full Web & WASM Compatibility: Zero native desktop/web crashes.
  • 🔗 Direct URL Import: Built-in network downloader integrated right into the picker pipeline.

📦 Pub.dev: https://pub.dev/packages/adaptive_image_picker
💻 GitHub: https://github.com/Karan8686/adaptive_image_picker

Would love your feedback, feature suggestions, or issue reports!


r/FlutterDev 1d ago

Article Writing an EditableText widget from scratch

5 Upvotes

I wrote a tutorial how to create a simple version of an EditableText from scratch, because I wanted to learn how to do this. And yes, it was me and it took like 8h hours which seems to be wasteful in the age of AI. But I used to like to write deep-dives like this, so I did it anyway.


For a bit of retro fun, I created an AText widget that paints a text using a crisp pixel font without antialiasing, something Text isn't capable of. Here's the API:

class AText(
  final String data, {
  final TextStyle? style,
})

For compatibility, I support a TextStyle but ignore everything but the color property. The font has a width and height of 8 pixels.

Now I want to also create an AEditableText widget for text input. The original EditableText plus its RenderEditable clocks at over 10000 lines of code. Obviously, I can't use it because because it uses the usual font rendering mechanism. So, how to approach this?

Here's the API I came up with:

class AEditableText({
  super.key,
  required final TextEditingController controller,
  required final FocusNode focusNode,
  final TextStyle? style,
  final Color? cursorColor,
}) extends StatefulWidget {
  ...
}

I'll only support a single line of text which cannot scroll. I'll probably also only support a subset of keyboard shortcuts and minimal mouse interaction.

Continued here.

I accidentally broke web support, but I might be inclined to fix that and provide a demo DartPad.


r/FlutterDev 19h ago

Plugin I got tired of Google Drive image links breaking my Flutter apps, so I made a package for it

0 Upvotes

Anyone who's tried showing a Google Drive or Dropbox "shared" image link directly in Image.network knows the pain — broken previews, weird redirects, manual URL conversion hacks. Made a small package to fix this: adaptive_image_loader.

It's basically a drop-in replacement for Image.network that auto-detects and handles:

  • Google Drive share links
  • Dropbox share links
  • Normal public image URLs

Plus optional disk caching (via cached_network_image) that you can toggle with a single boolean — no separate widget tree needed.

dart

AdaptiveImage.driveImage(
  'https://drive.google.com/file/d/FILE_ID/view',
  width: 300,
  height: 200,
);

Also ships an AdaptiveImageProvider if you need it as a background/avatar image (works with CircleAvatar, DecorationImage, etc).

Null-safe, lightweight, MIT licensed.

pub.dev: https://pub.dev/packages/adaptive_image_loader
GitHub: https://github.com/Karan8686/adaptive_image_loader

Would love feedback/issues if you try it out — this is an early release so open to feature requests (S3, Firebase Storage links maybe next).


r/FlutterDev 1d ago

Tooling Postgres full-text search, RPC calls, and upsert now available in FlutterFlow's Supabase integration

Thumbnail
youtube.com
1 Upvotes

we just shipped four Supabase updates in FlutterFlow today that might be useful for anyone building data-heavy Flutter apps:

infinite scroll: enable at the bottom of any Supabase query, set a page size. returns 25 rows on load, fetches the next 25 when the user reaches the bottom.

full-text search: Search (Full-Text) filter backed by Postgres full-text search. "roasting garlic" still matches "roasted." no custom function required.

RPC calls: call Postgres database functions directly from an action flow. function signatures sync from your Supabase project so parameters are listed automatically and results come back typed and bindable. useful for anything complex enough to warrant a database function — the demo uses a recipes_i_can_make function that walks ingredient lists against a pantry.

upsert: insert or update in one action based on primary key or chosen on-conflict columns. replaces the read-then-branch-then-write pattern.

happy to answer questions about the implementation.


r/FlutterDev 1d ago

Article What's your favorite way to shrink a labelled divider?

0 Upvotes

It is surprisingly difficult make this widget to properly shrink horizontally:

class Separator({final Widget? title}) extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    if (title case final title?) {
      return Row(
        spacing: 4,
        children: [
          const Expanded(child: Divider()), 
          title, 
          const Expanded(child: Divider()),
        ],
      );
    }
    return Divider();
  }
}

There's an overflow if the available width is less than the width required for title. Obviously (which was the first thing AI suggested) wrapping title in some kind of Flexible doesn't work.

There are (at least) three solution, all with trade-offs:

1) Use a Stack to place title over a Divider. This requires a known background color so you can wrap title in a Container with some padding and that background color.

2) Use a CustomMultiChildLayout to layout title with loose constraints, learning about its width in that process and then layouting the two dividers in the remaining space, if there's any. However, because the container itself grabs all space available, it has no fix height and you'd need to set that explicitly.

3) Use a LayoutBuilder to get the available width, then constrain the title to that value minus spacing, relaxing the min width to 0. This delays layout by one frame and I've still a minimum size of 8.

Did I miss something? What's your preferred solution?


r/FlutterDev 1d ago

Tooling CodeScout: free, self-hosted logging and network inspection for Flutter, with live device pairing and an on-device database browser

0 Upvotes

I have been building Flutter apps for over four years, and the thing that never stopped hurting is what happens after a build leaves my machine. On my desk the app is transparent. On a tester's phone it is a black box, and every question is a round trip.

So I built CodeScout. It is MIT licensed and you host it yourself: a Dart SDK in the app and a Go + Postgres dashboard on your own box.

What it does:

- Captures logs and HTTP calls (interceptors for dio and package:http), stores them in SQLite on the device, and syncs batches to your server
- A panel inside the app: the tester sees logs, network calls and errors on the phone, with no server configured at all
- Sessions as full timelines, errors grouped by shape across devices, every device with its OS and app version
- Live pairing: type a short code from the dashboard into the app and watch that phone's logs and network calls arrive as it is used
- While paired, browse the app's own SQLite, shared_preferences and Hive boxes from the dashboard. Nothing is readable until the app registers it, nothing writable unless it says so
- An MCP server with 18 read-only tools, so a coding agent can read a session instead of you pasting logs into it
- Redaction is opt-in and happens on the device before anything is written or uploaded

What it is not: a crash reporter (run one alongside it), a DevTools replacement (DevTools is better while the cable is in), or a hosted service (there is no account and nothing of mine in the middle).

Repo: https://github.com/getcodescout/code_scout
SDK: https://github.com/getcodescout/code_scout_flutter
Docs: https://codescout.tech
pub.dev: https://pub.dev/packages/code_scout

It is at 1.0 and everything above works today. I would genuinely value criticism from people who ship Flutter apps to real testers: what feels wrong, what is missing, what you would never allow in a build you distribute.


r/FlutterDev 1d ago

Video building a tracing app with flutter and chatgp adding ads

Thumbnail
youtube.com
0 Upvotes

r/FlutterDev 1d ago

Discussion Does importing Plugins make my code a Plugin or can it be a Package?

1 Upvotes

I'm building a 'voice agent' for flutter apps. It pulls in a bunch of dependencies but in particular, these guys to handle the voice parts...

  flutter_tts: ^4.2.3
  speech_to_text: ^7.2.0

Both of these are plugins with native code for Android and IOS. My codebase has no native code for IOS or Android. It is *currently* configured as a plugin but the platform stuff is all empty boilerplate and I have written no custom IOS/Android code for it.

abstract class MyVoiceAgentPlatform extends PlatformInterface {
  MyVoiceAgentPlatform() : super(token: _token);
  static final Object _token = Object();
  static MyVoiceAgentPlatform _instance =  MethodChannelMyVoiceAgentPlatform();
  static MyVoiceAgentPlatform get instance => _instance;
  static set instance(MyVoiceAgentPlatform instance) {
    PlatformInterface.verifyToken(instance, _token);
    _instance = instance;
  }
  Future<String?> getPlatformVersion() {
    throw UnimplementedError('platformVersion() has not been implemented.');
  }
}

So can I 'downgrade' my code to a package instead of a plugin? I'm confused. It has no native code itself so it that says 'package' but it pulls in dependencies which do have native code so it isn't really usable in a pure dart context.

Is the 'Plugininess' of the dependencies transitive?


r/FlutterDev 1d ago

Tooling Flutter is unbundling Material & Cupertino into standalone packages (material_ui & cupertino_ui). Here’s how to automate the migration with AI.

0 Upvotes

Flutter is decoupling Material and Cupertino from the monolithic core framework into standalone packages on pub.dev: package:material_ui and package:cupertino_ui.

This brings independent release cycles and true headless app support (package:flutter/widgets.dart), but also means migrating existing codebases.

Because of training cutoffs, most AI coding assistants (Google Antigravity, Claude Code, Cursor, Copilot, Cline) still generate legacy monolithic imports.

To fix this, we updated the open-source dart-sdk-skills repository with complete migration runbooks. You can install it globally for your AI agent in seconds:

npx skills add RandalSchwartz/dart-sdk-skills -g

Then simply prompt your agent:
👉 "Migrate this project to the new split Material & Cupertino packages."

Your agent will automatically run dart fix --apply --code=migrate_design_widgets, update pubspec.yaml, rewrite imports to package:material_ui/material_ui.dart, and verify everything passes dart analyze.

Question for the community:
Are you planning to migrate your apps directly to material_ui/cupertino_ui, or take advantage of the decoupling to build custom headless design systems?


r/FlutterDev 1d ago

Tooling Agents when coding

0 Upvotes

Hi. I am a fair to middling Flutter developer. I mostly use LLMs to review what I write rather than write my code. This works out well because I seem to be particularly good and repeating the same mistakes.

Anyway, I decided to publish this: Https://github.com/bjrochem72/flutter-audit-skills and would welcome constructive feedback and suggestions.

I am currently working on both updating it and adding to it. The problem is when I add a new item I suddenly see a bunch of things I should fix and don’t want to embarrass myself.

Anyway, I am sharing this in the hope it helps someone else as I have gotten a lot from this group and wanted to see if I could find a way to give back a bit.

My usual user id is bjr201 but I couldn’t post under that.


r/FlutterDev 2d ago

Plugin iconmind_flutter — 2,041 open-source icons for AI-era apps (agents, MCP, RAG, vector DBs…), drawn as CustomPaint strokes instead of a font, with duotone and three weights

5 Upvotes

I maintain IconMind, an MIT-licensed icon set for the vocabulary that generalist icon sets don't have — agents, tool calls, MCP servers, RAG pipelines, embeddings, evals, guardrails — plus the ordinary stuff (arrows, files, charts, DevOps, cloud, security) so you don't need a second set beside it.

Version 0.4.0 just doubled the collection to 2,041 icons, and the Flutter package is now available on pub.dev.

Install

flutter pub add iconmind_flutter

Usage

import 'package:iconmind_flutter/iconmind_flutter.dart';

IconMind(IconMindIcons.agent)

IconMind(
  IconMindIcons.vectorDatabase,
  variant: IconMindVariant.duotone,
  weight: IconMindWeight.bold,
  size: 32,
  color: Colors.deepPurple,
)

What's different from dropping in an icon font?

1. Six drawings per icon

Every icon comes in:

  • Outline — Thin
  • Outline — Regular
  • Outline — Bold
  • Duotone — Thin
  • Duotone — Regular
  • Duotone — Bold

That's 12,246 drawings in total.

Duotone uses a second tinted layer behind the strokes. A font would flatten that into a single filled glyph, so the package instead draws real paths with CustomPaint.

2. Tree-shaking actually works

Each icon is a compile-time const, one per file, and referenced through:

IconMindIcons.<name>

Flutter's AOT compiler can drop icons you don't reference. An app showing three icons carries roughly three icons — about 400 bytes each.

The entire package is only 214 KB compressed on pub.dev, with no assets or fonts to bundle.

3. Real weights, not faked weights

The three weights share the same geometry with different stroke widths.

Using:

absoluteStrokeWidth: true

keeps the stroke constant when scaling the icon. So a 16 px icon in a dense list and a 48 px icon in an empty state still look like they belong to the same set.

4. Machine-validated

Everything is drawn on a 24 px grid by a compiler that refuses geometry it can't draw correctly, including:

  • Off-grid anchors
  • Stroke runs that disappear at bold weight
  • Icons that don't fill the box consistently with the rest of the set

A nightly scan rasterises all 12,246 cells and checks for duplicate-looking renders.

That's how 2,000+ icons stay visually consistent as one set.

5. Built for accessibility and multiple platforms

color falls back to the ambient IconTheme, while semanticLabel is announced by screen readers.

The same icons are also available as packages for:

  • React
  • Vue
  • Svelte
  • Solid
  • Preact
  • React Native
  • Astro
  • Laravel

Everything is generated from a single source, which is handy when web and mobile teams share a design system.

Browse the icons

Website: https://iconmind.dev

Every icon is searchable by name, tag, or alias, with the Flutter snippet available for whichever icon you find.

There's also an MCP server:

npx @iconmind/mcp

This lets your coding assistant pick icon names instead of guessing them.

Links

MIT means commercial use, no attribution, and no seat count.

I'm the author, and I'd genuinely like to hear what's missing.

Most of the last thousand icons came from people saying:

"There's no icon for X."

If there's something you think should be in the set, let me know.