§
§ · flutter development

Flutter, one language, five targets.

A Dart-first Flutter practice for brands needing one codebase that ships to iOS, Android, web, Windows, macOS, Linux, and embedded targets with pixel-identical UI and the Impeller renderer.

§ 01 · one language, five targets

Flutter compiles one Dart codebase to five runtimes.

Flutter's thesis is different from React Native's: instead of bridging to native platform widgets, Flutter draws every pixel itself through the Impeller renderer. The payoff is pixel-identical UI across every platform and a single codebase that compiles to iOS, Android, web, Windows, macOS, Linux, and embedded targets. The cost is a larger binary size and less access to platform-idiomatic widgets by default. For brands where "one UI everywhere" outweighs "native look", Flutter wins.

target 01 · ios

AOT native ARM compile. Impeller renderer default. Cupertino widgets for platform-idiomatic UI.

target 02 · android

AOT native ARM + x64. Material 3 default. Impeller opt-in.

target 03 · web

Dart → JS or WASM. CanvasKit for pixel parity, HTML renderer for lighter output. Right for internal tools.

target 04 · desktop

macOS, Windows, Linux stable. Native windowing, menus, file system.

target 05 · embedded

ARM Linux, automotive, kiosk via Flutter Embedder. Specialist territory.

§ 02 · the widget bloom

One tree. Five runtimes.

Flutter's widget tree renders identically on every platform because Flutter owns the rendering layer. The animation below visualises how Dart compiles to each of the five targets.

Fig. 1 · widget bloom · one tree, five platforms
§ 03 · flutter vs react native

Two good frameworks. Two different teams.

dimensionFlutterReact Native
renderingImpeller (Flutter owns pixels)bridges to native widgets
UI parity across platformspixel-identicalnative-feeling on each
target platformsiOS, Android, web, desktop, embeddediOS, Android (web/desktop via 3rd party)
languageDartTypeScript
binary sizelarger (ships renderer)smaller
OTA updatesnot official; via ShorebirdEAS Update first-class
best formulti-platform, UI-consistent, Dart teamsReact teams, mobile-first, OTA velocity
§ 04 · state management

Riverpod first. BLoC for enterprise.

Flutter's state management landscape has stabilized. For new builds we default to Riverpod plus freezed for immutable data. BLoC for large enterprise teams that prefer explicit event-driven architecture. Provider only for legacy migrations. GetX we avoid in production.

Editorial Flutter widget tree showing MaterialApp branching through Scaffold to AppBar, Body, and FAB, with a compile-target arrow fanning out to five labeled platform columns iOS, Android, Web, Desktop, and Embedded.
Fig. 2 · one tree, five targets · Flutter widget tree compiling to each platform
default · riverpod

Type-safe, testable, composable.

Successor to Provider by the same author. Compile-time dependency resolution. Family providers for parameterized state. AsyncValue for async data with loading/error states.

enterprise · bloc

Explicit events + states.

Event-driven architecture. Separation of business logic from UI. Heavier boilerplate, stronger discipline. Right pick for large teams valuing explicitness over terseness.

legacy · provider

Predecessor to Riverpod.

Acceptable for small apps or ongoing maintenance of Provider codebases. New builds should prefer Riverpod; the conceptual leap is small and the type safety is better.

§ 05 · platform channels

Dart calls Swift and Kotlin. Two-way.

When Flutter needs to reach into native APIs (CoreBluetooth, HealthKit, Android Keystore), it uses Platform Channels. MethodChannel for one-off calls, EventChannel for native event streams. Most common native integrations already have well-maintained pub.dev packages wrapping the platform calls. For truly custom needs we write a Flutter plugin containing Swift + Kotlin code exposed to Dart through a channel.

tier 01

Use a maintained pub.dev plugin (camera, location, biometrics, push).

tier 02

Write a custom plugin with Swift + Kotlin when the need is unique.

tier 03

FFI for direct C/C++ interop when performance or a native library is required.

§ 06 · performance SLA

Impeller and 60 FPS at rest.

metrictargetnotes
cold start< 2.0smid-tier Android, AOT build
frame rate60 fpsImpeller renderer, sustained
release APK size< 20 MBABI split enabled
crash-free> 99.6%Firebase Crashlytics, 30-day
§ 07 · proof

Two archetypes. One multi-platform, one mobile-first.

archetype 01 · fintech brand

iOS + Android + web from one codebase.

Consumer fintech on iOS, Android, and a progressive web app for account access from any browser. Riverpod, freezed, Firebase Auth, Plaid integration via platform channels. 18 weeks to production on all three targets.

targets
3
one codebase
code shared
94%
across targets
rating
4.8
App Store
archetype 02 · logistics operator

Driver app with offline + barcode.

Driver companion app for a logistics company. Offline route lists, barcode scanning via custom Flutter plugin, signature capture, photo upload queue. BLoC for state. 14 weeks.

drivers
1,200
daily active
cold start
1.6s
Android p75
offline hrs
8
before sync
§ 08 · engagement + fit

Four shapes. Audit names the right one.

shape 01

Readiness audit.

2 weeks. Platform fit, state reco, channel surface. Refundable.

shape 02

MVP.

10-16 weeks. iOS + Android + store submit.

shape 03

Production build.

14-22 weeks. Platform channels, offline, IAP, CI/CD.

shape 04

Multi-platform.

16-26 weeks. Mobile + web + desktop from one codebase.

right fit
  • You ship to beyond mobile (web, desktop, embedded)
  • Pixel-identical UI across platforms is a requirement
  • Your team has Dart experience or prefers object-oriented typing
wrong fit
  • ×Public content web site (SEO-critical); Flutter Web is wrong choice
  • ×Your team is React-native; React Native fits better
  • ×OTA JS-update velocity is critical; RN + EAS is first-class
§ 09 · questions

Eight answers.

Flutter vs React Native - which should we pick?

Three signals favor Flutter. One, you need to ship beyond mobile (web, desktop, embedded) and want one codebase across all of them. Two, you want pixel-identical UI across iOS and Android because Flutter draws every pixel itself via its own renderer rather than relying on native widget translations. Three, your team has or prefers Dart, or they come from a strong object-oriented background where Dart's type system fits. Three signals favor React Native. One, your team is deeply React and TypeScript already. Two, the app is mobile-only and OTA update velocity matters. Three, the ecosystem of JavaScript libraries matters more than the Flutter widget library. Neither is wrong; they are two excellent frameworks for different team shapes.

How much does a Flutter app cost in 2026?

US and UK senior Flutter engineers are $135 to $190 per hour; Indian senior engineers are $80 to $130 per hour. A Flutter MVP with Material 3 + Cupertino UI, 15 to 25 screens, auth, push, and store submission runs 10 to 16 weeks. A full production build with platform channels, offline sync, IAP, and custom CI/CD runs 14 to 22 weeks. A multi-platform build targeting mobile + web + desktop runs 16 to 26 weeks. A 2-week audit is refundable. Scoped quote in 48 hours.

Is Flutter good for web apps?

For internal tools, dashboards, and progressive web apps shared with mobile, yes. Flutter Web via CanvasKit renderer gives pixel-identical UI to mobile, which is useful when the experience needs to match. For public content-heavy web sites (SEO-critical, large-first-load-sensitive), Flutter Web is rarely the right choice; the initial bundle is large and SEO support is limited. Our rule: Flutter Web is right when the web target is an internal or authenticated experience; wrong when it is a public marketing or content surface.

Riverpod, BLoC, or Provider - which state management?

Riverpod for most new builds. It is the successor to Provider by the same author, with stronger type safety, testable providers, and compile-time dependency resolution. BLoC for teams that prefer explicit event-driven architecture, common in large enterprise apps. Provider for smaller apps or teams migrating from older Flutter codebases where Provider is already in use. We avoid GetX for production builds. The right default for a new Flutter project in 2026 is Riverpod plus freezed for immutable data classes.

How do you handle native platform-specific code?

Platform channels. Flutter's MethodChannel and EventChannel let Dart code call Swift or Kotlin methods on each platform. For common needs (camera, location, push, biometrics), we use maintained pub.dev packages that wrap the native APIs. For truly custom needs we write a Flutter plugin: Swift code for iOS, Kotlin for Android, exposed to Dart through a channel. The plugin lives in a separate package for reusability. Most Flutter apps need 2 to 5 custom native integrations, all wrapped in plugins.

Material 3 or Cupertino - do we pick one?

Usually not. The pragmatic pattern: Material 3 as the primary design system for Android with dynamic color and modern Material UI affordances. Cupertino widgets used on iOS for native-feeling navigation bars, action sheets, and sliders where platform expectation matters. Most of the app (buttons, inputs, layout) uses a shared design system that works on both. We build a design system on top of Material 3 with brand tokens, then override with Cupertino equivalents only where the iOS user expectation would be broken otherwise.

What's CI/CD look like for Flutter?

Three options. Codemagic for Flutter-native CI/CD with first-class support for iOS and Android builds, App Store and Play Store submission, and Flutter-specific test running. Fastlane with GitHub Actions or GitLab CI for teams already on those platforms, with the fastlane-plugin-flutter gem. Bitrise for teams needing a mobile-specific but more configurable pipeline. We pick based on the team's existing CI/CD surface; all three work. Signed builds happen in CI; no manual Xcode exports in 2026.

Who owns the code and credentials on exit?

You do. Private GitHub repository under your organization. Apple Developer Program and Google Play Developer Console under your legal entity. Signing certificates in your keychain and keystore (we keep encrypted backups for CI but you own the originals). Push notification providers, analytics, crash reporting all under your billing. DH engineers are named collaborators, removable any time. On exit: repository transferred, credentials rotated, documentation handed off, 30-day support tail.

Start with a readiness audit.

Two weeks. Platform fit, state recommendation, native channel surface, store readiness. Refundable. Scoped quote in 48 hours.