Files
2nd/10_Wiki/Topics/Frontend/JSI (JavaScript Interface).md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

6.2 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-jsi-javascript-interface JSI (JavaScript Interface) 10_Wiki/Topics verified self
React Native JSI
JavaScript Interface
RN New Architecture
none A 0.9 applied
react-native
jsi
performance
native-modules
2026-05-10 pending
language framework
cpp react-native

JSI (JavaScript Interface)

매 한 줄

"매 bridge 의 JSON serialization 의 제거 — 매 sync, direct C++ binding". React Native 의 New Architecture 의 foundation. 매 native function 을 C++ 객체로 expose, JS 가 매 sync 호출 + shared memory 접근. 매 old bridge 의 async-only / serialize-everything 의 근본 해결.

매 핵심

매 old bridge 문제

  • 모든 JS↔Native 호출 의 JSON serialize → message queue → async dispatch.
  • 매 frame 마다 hundreds of message — main thread blocking.
  • Image, animation 의 latency 누적.

매 JSI 솔루션

  • HostObject: C++ object 가 JS prototype 처럼 expose.
  • Sync calls: 매 native function 의 즉시 invoke (no queue).
  • Shared memory (ArrayBuffer): 매 zero-copy data exchange.
  • TurboModules: JSI 기반 native module — lazy-loaded, typed.
  • Fabric: JSI 기반 renderer — synchronous layout.

매 응용

  1. Reanimated 3+: UI thread 에서 매 worklet 의 sync 실행 (60→120Hz).
  2. MMKV: native key-value store 의 sync access (AsyncStorage 의 100x).
  3. VisionCamera: frame processor 의 native↔JS 의 zero-copy.

💻 패턴

TurboModule — JS 측 spec

// NativeCalculator.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
  add(a: number, b: number): number; // 매 sync return
  sha256(input: string): Promise<string>;
  getConstants(): { version: string };
}

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

TurboModule — iOS 구현

// Calculator.mm
#import "Calculator.h"
#import <RNCalculatorSpec/RNCalculatorSpec.h>

@implementation Calculator
RCT_EXPORT_MODULE()

- (NSNumber *)add:(double)a b:(double)b {
  return @(a + b); // 매 sync, no bridge
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
    (const facebook::react::ObjCTurboModule::InitParams &)params {
  return std::make_shared<facebook::react::NativeCalculatorSpecJSI>(params);
}
@end

HostObject — direct C++ binding

// MyHostObject.cpp
#include <jsi/jsi.h>
using namespace facebook::jsi;

class MyHostObject : public HostObject {
 public:
  Value get(Runtime& rt, const PropNameID& name) override {
    auto n = name.utf8(rt);
    if (n == "fastFunction") {
      return Function::createFromHostFunction(
        rt, name, 1,
        [](Runtime& rt, const Value&, const Value* args, size_t) -> Value {
          double x = args[0].asNumber();
          return Value(x * 2.0); // 매 sync, no JSON
        });
    }
    return Value::undefined();
  }
};

void install(Runtime& rt) {
  auto obj = std::make_shared<MyHostObject>();
  rt.global().setProperty(rt, "myNative", Object::createFromHostObject(rt, obj));
}

Reanimated worklet (JSI 활용)

import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';

function Box() {
  const x = useSharedValue(0); // 매 UI thread shared
  const style = useAnimatedStyle(() => ({
    transform: [{ translateX: x.value }],
  })); // 매 worklet, UI thread 에서 sync 실행

  return (
    <Animated.View style={style} onTouchEnd={() => {
      x.value = withSpring(100); // 매 JSI 의 sync update
    }} />
  );
}

MMKV (sync storage)

import { MMKV } from 'react-native-mmkv';
const storage = new MMKV();

storage.set('user.id', '123'); // 매 sync, no Promise
const id = storage.getString('user.id'); // 매 sync
// AsyncStorage: await storage.getItem(...) — 매 ms 단위 latency

VisionCamera frame processor

import { useFrameProcessor } from 'react-native-vision-camera';
import { detectFaces } from 'vision-camera-face-detector';

function Scanner() {
  const frameProcessor = useFrameProcessor((frame) => {
    'worklet';
    const faces = detectFaces(frame); // 매 native, zero-copy
    runOnJS(setFaces)(faces);
  }, []);
  return <Camera frameProcessor={frameProcessor} />;
}

Fabric component (synchronous layout)

// MyViewNativeComponent.ts
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
import type { ViewProps } from 'react-native';

interface NativeProps extends ViewProps {
  color?: string;
}
export default codegenNativeComponent<NativeProps>('MyView');

매 결정 기준

상황 Approach
RN 0.68+ 새 project New Architecture (Fabric+TurboModules) enable
Sync native 필요 TurboModule + JSI
Animation 60+ FPS Reanimated 3 worklet
Storage sync MMKV (JSI) over AsyncStorage
Frame-by-frame ML VisionCamera + JSI worklet

기본값: New Architecture, TurboModules, Reanimated 3.

🔗 Graph

🤖 LLM 활용

언제: RN 의 native module 작성, performance bottleneck 진단, sync API 필요. 언제 X: 매 plain JS-only feature, Expo Go 환경 (custom native 의 X).

안티패턴

  • JSI sync function 에서 heavy work: JS thread block — 매 worklet / native thread 사용.
  • HostObject 의 reference 누수: shared_ptr cycle — Runtime invalidate 시 crash.
  • Old bridge + JSI 혼용: serialization overhead 잔존, 매 New Architecture full migration.
  • Reanimated worklet 에서 closure capture 무분별: 매 'worklet' directive 누락 시 silent fall-back to JS thread.

🧪 검증 / 중복

  • Verified (reactnative.dev/architecture, RN 0.76 New Architecture default 발표).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — JSI + TurboModules 패턴 정리