This skill provides step-by-step guidance on implementing a decoupled architectural design where a headless Flutter engine acts as the shared single source of truth (SSOT) running in the background, while the user interfaces are built using platform-native toolkits.
graph TD
subgraph Native Frontends
iOS[SwiftUI View]
Android[Jetpack Compose]
Web[Web Components / JS]
end
subgraph Headless Flutter Context
Engine[Flutter Engine]
StateManager[State Manager / Tasks]
Bridge[Platform Channels / Interop]
end
iOS <-->|Pigeon IPC| Bridge
Android <-->|Pigeon IPC| Bridge
Web <-->|dart:js_interop| Bridge
Bridge <--> StateManager
Pigeon is used for type-safe IPC communication between Dart and Swift/Kotlin.
Create a pigeon definition file at pigeons/tasks_api.dart:
@HostApi for calls originating from native code that Dart answers.@FlutterApi for calls originating from Dart that native platforms listen to.Compile the interfaces using the Pigeon CLI:
dart run pigeon --input pigeons/tasks_api.dart
Use dart:js_interop to bind functions to the global window object:
@JS('window.methodName') setters to bind Dart triggers.@JS('window.callbackName') getters to notify host JS components of updates.Instantiate FlutterEngine without a visual viewport controller:
var flutterEngine: FlutterEngine?.let engine = FlutterEngine(name: "my-engine") and call engine.run().TaskStore) to listen on the binary messenger:
store.setup(binaryMessenger: engine.binaryMessenger).UIHostingController and present it in the main UIWindow.Instantiate a headless FlutterEngine inside a standard Compose activity:
onCreate in a subclass of ComponentActivity.FlutterEngine(this) and invoke executeDartEntrypoint(...).dartExecutor.binaryMessenger.setContent { ... }.flutterEngine.destroy() on onDestroy().Boot Flutter Web headlessly by specifying a hidden target container:
flutter_bootstrap.js mapping:engineInitializer.initializeEngine({
hostElement: document.getElementById('flutter-host') // Styled with display: none
})
Native clients should observe updates from the headless engine reactively:
ObservableObject and dispatch events to SwiftUI views via @Published properties on DispatchQueue.main.async.StateFlow updated via the Pigeon host API callback. Connect Compose views using .collectAsState().toggle-task, delete-task) up the DOM hierarchy.The resource folder contains CLI compilation check scripts:
resources/check_ios.sh: Validates Swift compilation and framework linkage.resources/check_android.sh: Triggers Kotlin compile tasks to catch build errors before simulator deployment.