How it works

Architecture

Pipeline: Android and Apple SDK inputs are parsed into the Native IR, planned per target and emitted as Dart and TypeScript bindings with small runtimes.
android.jar + api-versions.xml + annotations.zip ─┐
Xcode SDK headers (libclang) ─────────────────────┼─▶ Native IR ─▶ planner ─▶ emitters ─▶ Dart / TypeScript
Swift symbol graphs (swift-symbolgraph-extract) ──┘   (JSON,          (per target:     + small runtimes
                                                       stable IDs)     what is possible)

Native IR

A platform-neutral, deterministic model: types, members, generics, nullability, per-platform availability, threading and provenance, with stable symbol IDs such as android.content.Intent#setData(android.net.Uri) or UIKit.UIView#-initWithFrame:. Every symbol carries a support status and, when it is not generated, a reason code.

Parsers

Emitters and runtimes

TargetGeneratedRuntime
Flutter / AndroidDart extension types, cached JNI method IDspackage:jni + a small Dart runtime
Flutter / iOSDart extension types, typed objc_msgSend trampolinespackage:objective_c
React Native / AndroidTypeScript classes + member tablesC++ JSI runtime (JNI)
React Native / iOSTypeScript classes + member tablesObjective-C++ JSI runtime (NSInvocation)
What happens on a call: app code calls the generated binding, the runtime dispatches to JNI or the Objective-C runtime, and the result is converted back.

For React Native the generated C++ is data (sorted tables), so one runtime serves every API. Method signatures on iOS come from the Objective-C runtime itself; the generator only says how each value maps to JavaScript.

Determinism and safety