Skip to content

Installation

The quick start showed the round trip in isolation. This page is the setup that gets BridgeKit into a real app on each platform: where the native runtime comes from, how it is initialized, and the packaging constraints that matter.

BridgeKit’s transport is built on Nitro modules. On both platforms the runtime arrives through your app’s existing React Native native-module wiring — autolinking — rather than a dependency you add by hand. You initialize the runtime once at process start, then provide/consume contracts as shown in Using BridgeKit.

The Android runtime is the most mature target — full bidirectional round trips (async, fire, streams, state) run on a real device or emulator. Setup is three moving parts: the dependency, the one-time initialization, and provider auto-discovery.

  1. Add the BridgeKit dependency. BridgeKit is a React Native native module backed by react-native-nitro-modules; it ships as an AAR consumed through your app’s existing React Native / Gradle setup. The Nitro headers are delivered as a Prefab AAR (buildFeatures.prefab = true), and a single libBridgeKit.so is built per ABI (armeabi-v7a, x86, x86_64, arm64-v8a).

  2. Initialize the runtime before React Native. Call BridgeKit.default.initialize(host) before ReactManager.initialize(). The initialization seeds the Nitro native delegate (the Router) that every inbound call lands on.

    val bridgeKit = BridgeKit.default
    bridgeKit.initialize(host)
    // … then ReactManager.initialize(...)
  3. Register providers in the provide window. Provider discovery must run before ReactManager.initialize() as well — that is the window in which contracts are provided so the JS side can resolve them on first connect. You can register explicitly:

    bridgeKit.provide(MyHostContract, Scope.Global, eager = true) { MyHostImpl() }

    …or let ServiceLoader-based auto-discovery register feature providers for you. See Discovery & auto-registration for the ServiceLoader contract and the R8 keep rules it needs.

Once initialized, implementing and registering a provider is covered in Kotlin: provide & consume.

iOS is at parity with Android — the same four markers run on-device, validated end to end. Setup is four moving parts: the pod, the build settings the Nitro/C++ seam needs, the generated Swift files, and the one-time initialization.

  1. Add nothing to the Podfile. BridgeKit ships one podspec at the package root (BridgeKit.podspec), which React Native autolinking resolves out of node_modules. The example app’s Podfile is the stock React Native template with no BridgeKit line in it, and pod install still picks the pod up:

    apps/example/ios/Podfile.lock
    - BridgeKit (from `../node_modules/@malopezr7/bridgekit`)

    Run pod install as you normally would.

  2. Set three build settings on the app target. BridgeKit is a Nitro-backed Swift module with C++ interop, and the consuming target currently has to opt into that seam itself:

    SWIFT_OBJC_INTEROP_MODE = objcxx
    HEADER_SEARCH_PATHS = $(inherited) $(PODS_ROOT)/Headers/Private/NitroModules
    OTHER_LDFLAGS = $(inherited) -ObjC -lc++

    These are exactly what the example app carries, in both Debug and Release (apps/example/ios/BridgeKitExample.xcodeproj).

  3. Add the generated Swift files to the target. bridgekit generate --platform swift writes one <PascalName>Contract.swift per contract. Xcode does not glob a directory, so the files must be added to the target’s Compile Sources or they are silently not built. They declare their types without an access modifier, which means they compile as part of your target — there is no generated module to import. Your own Swift imports BridgeKit and nothing else.

  4. Initialize the runtime from the AppDelegate, before React Native starts — the mirror of Android’s MainApplication.onCreate:

    func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
    window = UIWindow(frame: UIScreen.main.bounds)
    // Register providers before JS loads.
    BridgekitDemoInitializer.configure()
    factory.startReactNative(
    withModuleName: "BridgeKitExample",
    in: window,
    launchOptions: launchOptions
    )
    return true
    }

    Inside configure(), BridgeKitRuntime.default.provide(Contract(), scope: .global) { impl } registers each provider. See Swift: provide & consume.

You do not need to import NitroModules in app code.