Skip to content
xcross
Documentation menu

Architecture

A deep dive into how xcross reimplements the iOS build, signing and CoreDevice launch pipeline for Flutter and Compose Multiplatform in pure Dart.

A thin CLI over focused Dart packages. Two front ends (Flutter, Compose) share one back end (SDK, signing, device).

Flutter front endengine cache · frontend_server · SwiftPM plugins
Compose front endGradle klib · konanc framework · ObjC/Swift runner
Native back endDarwin SDK · clang · ld64.lld · .app assembly
SigningGrandSlam + ADI · provisioning · in-process codesign
DeviceRSD tunnel · CoreDevice launch · gdb-remote attach

Pipelines

xcross flutter run
   ├─ FlutterPacker
   │    ├─ IosEngineCache        engine artifacts pinned to the SDK's engine hash
   │    ├─ FlutterDebugBundler   frontend_server → app.dill → App.framework (JIT)
   │    ├─ SwiftPM plugins       swift build → libFlutterPluginsGenerated.dylib
   │    ├─ RunnerShim            clang / ld64.lld → Runner Mach-O
   │    └─ assemble              Flutter.framework + Info.plist + assets → .app
   ├─ in-process codesign → install
   └─ CoreDeviceLauncher         RSD tunnel → launch suspended → gdb-remote attach
        └─ HotReloadController   DevFS + VM Service ⇄ frontend_server

Flutter: engine and kernel

  • Engine: downloads exactly what flutter would cache for your SDK’s engine hash. The engine is never modified. On Linux and Windows, SDK iOS artifacts are reused only when the FlutterEngine revision matches, so a stale precache can’t ship an “Invalid SDK hash” black screen.
  • Kernel: frontend_server compiles your Dart to app.dill. Debug mode is JIT, so no gen_snapshot, so no macOS.
  • Plugins: SwiftPM plugins build into one dylib with a generated registrant. CocoaPods-only plugins are skipped.
  • Dependencies: since 2.0, SwiftPM resolves the whole plugin graph natively. URL dependencies are no longer cloned or rewritten to path dependencies. An xcross manifest compiler applies host fixes to every manifest SwiftPM evaluates, without touching Package.swift.
  • Macros: SwiftUI, #Preview (including UIKit and widget previews) and FoundationModels macros expand through the Open Apple Macros server. Release bundles ship it prebuilt, so the first build doesn’t compile swift-syntax. tools.OpenAppleMacrosServer points at another server.
  • Assets: shaders compile with the host impellerc, like flutter build. Icon fonts are tree shaken in profile and release builds (--[no-]tree-shake-icons). Package licenses survive iOS builds.

Compose: Kotlin/Native

  • Toolchain: xcross compose setup fetches the Kotlin/Native prebuilt matching your project and patches its host config for the Darwin SDK.
  • Framework: konanc links the iOS framework. Inputs and flags are fingerprinted, so unchanged builds skip it (~145 s → ~12 s).
  • Runner: a generated ObjC host for ComposeUIViewController, or your SwiftUI @main.

Shared back end

Darwin SDKdarwin_sdk_kit unpacks Xcode.xip with pure-Dart xar/pbzx/cpio readers.
Native linkclang + ld64.lld against the SDK. No xcodebuild.
Signingapple_developer_kit: GrandSlam login, provisioning, Mach-O signing in Dart, offline from cached profiles.
Launchdart_mobile_device: RSD tunnel, CoreDevice launch, gdb-remote.

Flutter hot reload

Savefile watcher
Incremental compilefrontend_server
UploadDevFS over VM Service
ReloadreloadSources + reassemble

R resets the compiler, uploads a full dill and restarts each FlutterView. The frontend_server also serves expression evaluation for the debugger.

IDE debugging

xcross_dap is a DAP server over the same VM Service. VS Code reaches it through a shim that only intercepts "xcross": true configs, JetBrains through an LSP4IJ run configuration.

Packages

PackageRole
cli_kitLogging, spinners, process running
darwin_sdk_kitXcode archive extraction, SDK bundles
apple_developer_kitApple login, provisioning, codesign
dart_mobile_deviceTunnels, install, launch, port forwarding
frontend_server_kitIncremental kernel compile, hot reload
open_apple_macrosApple macro plugin server (SwiftUI, Previews, FoundationModels)
xcrossCLI, Flutter packer, Compose packer, DAP
ESC