---
id: mobile-native-module-bridging-deep
title: Native Module Bridging — RN / Flutter / KMP
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [mobile, rn, flutter, vibe-coding]
tech_stack: { language: "TS / Swift / Kotlin", applicable_to: ["Mobile"] }
applied_in: []
aliases: [native module, JSI, bridge, platform channels, FFI, Kotlin/Native, Swift/C interop]
---

# Native Module Bridging Deep

> Cross-platform 가 native API 호출. **RN JSI, Flutter platform channel, KMP expect/actual, FFI**.

## 📖 핵심 개념
- Cross-platform 가 매 native 의 wrap.
- Bridge / channel 가 cost.
- Modern: JSI (RN), MethodChannel (Flutter).
- KMP = native interop.

## 💻 코드 패턴

### React Native New Architecture (JSI)
```cpp
// NativeMyModule.h (TurboModule)
class NativeMyModule : public TurboModule {
public:
  facebook::jsi::Value getDeviceInfo(facebook::jsi::Runtime &runtime);
};
```

```ts
// JS
import NativeMyModule from './NativeMyModule';

const info = NativeMyModule.getDeviceInfo();
// → JSI = direct call. 빠름.
```

→ Old: JSON bridge (slow).
New: JSI (synchronous, fast).

### iOS (Swift)
```swift
// MyModule.swift
@objc(MyModule)
class MyModule: NSObject {
  @objc func getDeviceInfo(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
    let info = ['model': UIDevice.current.model]
    resolve(info)
  }
  
  @objc static func requiresMainQueueSetup() -> Bool {
    return true
  }
}
```

### Android (Kotlin)
```kotlin
class MyModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
    override fun getName() = "MyModule"
    
    @ReactMethod
    fun getDeviceInfo(promise: Promise) {
        promise.resolve(mapOf("model" to Build.MODEL))
    }
}
```

### TurboModule (modern RN)
```ts
// TS spec
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
  getDeviceInfo(): Object;
  multiply(a: number, b: number): number;
}

export default TurboModuleRegistry.getEnforcing<Spec>('MyModule');
```

→ Code generated. Type-safe.

### Flutter platform channel
```dart
// lib/my_module.dart
import 'package:flutter/services.dart';

class MyModule {
  static const channel = MethodChannel('my_module');
  
  static Future<Map> getDeviceInfo() async {
    return await channel.invokeMethod('getDeviceInfo');
  }
}
```

### Flutter iOS (Swift)
```swift
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(...) -> Bool {
    let controller = window?.rootViewController as! FlutterViewController
    let channel = FlutterMethodChannel(name: 'my_module', binaryMessenger: controller.binaryMessenger)
    
    channel.setMethodCallHandler { call, result in
      if call.method == 'getDeviceInfo' {
        result(['model': UIDevice.current.model])
      }
    }
  }
}
```

### Flutter Pigeon (type-safe)
```dart
// pigeons/messages.dart
@HostApi()
abstract class MyApi {
  @async
  Map<String, String> getDeviceInfo();
}
```

→ Codegen 가 native + Dart side.

### KMP (expect / actual)
```kotlin
// commonMain
expect class Platform() {
    val name: String
}

// androidMain
actual class Platform {
    actual val name = 'Android ${Build.VERSION.SDK_INT}'
}

// iosMain
actual class Platform {
    actual val name = 'iOS ${UIDevice.currentDevice.systemVersion}'
}
```

### KMP iOS interop
```kotlin
// iosMain
import platform.UIKit.UIDevice
import platform.Foundation.NSDate

fun getDate() = NSDate()
fun getDevice() = UIDevice.currentDevice
```

→ Apple SDK 가 Kotlin 안.

### Swift / C interop
```swift
// Swift 의 C function call
import Darwin

let pid = getpid()
```

```swift
// Swift 가 C struct
let buf = UnsafeMutablePointer<Int8>.allocate(capacity: 100)
strcpy(buf, 'hello')
```

### Rust FFI
```rust
#[no_mangle]
pub extern 'C' fn add(a: i32, b: i32) -> i32 {
    a + b
}
```

```c
// C header
int32_t add(int32_t a, int32_t b);
```

→ iOS / Android 가 Rust shared library.

### React Native + Rust
```ts
// react-native-uniffi.
// → Rust → JSI native module.
```

→ Cryptography, ML inference 친화.

### Performance
```
JSON bridge (옛 RN): 10-100 ms / call.
JSI / TurboModule: < 1 ms.
Flutter platform channel: ~1 ms.
KMP: ~ direct call (no bridge).
FFI: native speed.

→ Modern = bridge cost 거의 X.
```

### Codegen
```
RN: Codegen (TS spec → C++ binding).
Flutter: Pigeon.
KMP: 자체 (no codegen).

→ Type-safe + 빠른 development.
```

### Async vs sync
```
JSI (RN): sync 가능.
Platform channel (Flutter): async 만.
KMP: 매 (suspend OK).

→ Sync 가 약간 빠름 가, deadlock 위험.
```

### Threading
```
Native callback 가 main thread or background:
- iOS: dispatch_async.
- Android: Handler / Coroutine.
- 잘못 = crash.
```

### Plugin ecosystem
```
RN:
- npm install + auto-link (RN 0.60+).
- TurboModule 가 modern.

Flutter:
- pub.dev.
- Plugin 의 Dart + native.

KMP:
- Maven / CocoaPods.
- Compose Multiplatform.
```

### When NOT bridge?
```
- Pure UI: framework UI 가 충분.
- Network: HTTP client (cross-platform).
- Storage: SQLite / KV (cross-platform library).

→ Native API 만 (Bluetooth, sensor, AR) bridging.
```

### Real native vs bridged
```
Camera:
- Native: AVCaptureSession (iOS), CameraX (Android).
- Bridged: react-native-camera, image_picker (Flutter).

→ 매 platform 의 nuance.
Bridge 의 quality = library 따라.
```

### Bluetooth (예)
```
RN: react-native-ble-plx.
Flutter: flutter_blue_plus.
KMP: kable.

→ 매 가 native API 의 wrapper.
```

### ML (Core ML / TFLite)
```
RN: react-native-fast-tflite.
Flutter: tflite_flutter.
KMP: 자체 wrap.

→ Performance 가 native speed.
```

### Debug
```
Native crash:
- iOS: Xcode debug + symbol.
- Android: Logcat + adb.
- Flutter: flutter logs.
- RN: react-native log.

→ Native crash 가 cross-platform 의 어려움.
```

### Cross-platform library
```
- SQLite (모든).
- Realm (RN, Flutter).
- WatermelonDB (RN).
- Drift (Flutter).
- SQLDelight (KMP).

→ 1 library, 모든 platform.
```

### Type safety
```
TurboModule (RN): TS spec → 자동 type.
Pigeon (Flutter): Dart spec → 자동 type.
KMP: Kotlin types 가 native.

→ Manual writing 가 typo / drift 위험.
```

### Production tips
```
1. TurboModule / Pigeon (codegen).
2. Async wherever possible.
3. Native crash report (Sentry).
4. Test 가 매 platform.
5. Plugin 신중 선택 (maintenance).
6. Native module version pin.
```

### Common 함정
```
- Main thread block: ANR / freeze.
- Memory leak (callback ref).
- Native crash 가 silent.
- Plugin 의 maintainer 0.
- Old bridge (RN 0.60 이하).
- Synchronous on Flutter: 안 됨.
```

## 🤔 의사결정 기준
| Cross-platform | Native bridge |
|---|---|
| RN | TurboModule |
| Flutter | Pigeon (Dart + native) |
| KMP | expect/actual |
| Rust shared | FFI |
| Multi-FW | KMP |
| Native UI 도 | 매 native UI separate |

## ❌ 안티패턴
- **Old RN bridge**: slow.
- **Sync from main**: ANR.
- **Manual type binding**: drift.
- **Plugin 가 unmaintained**: vulnerable.
- **Memory leak in callback**: crash.

## 🤖 LLM 활용 힌트
- TurboModule (RN), Pigeon (Flutter), expect/actual (KMP).
- Codegen 가 type-safe + 빠른 dev.
- FFI 가 Rust / C interop.
- Native API 만 bridge (UI X).

## 🔗 관련 문서
- [[Mobile_RN_New_Architecture]]
- [[Mobile_KMP_Deep]]
- [[Mobile_Flutter_Patterns]]
