JSI (JavaScript Interface) — ay isang software layer sa React Native na nagbibigay ng direktang kasabay na access mula sa JavaScript papunta sa C++ objects at functions, na pinapalitan ang asinkronos na JSON bridge na Bridge. Hindi tulad ng hinalinhan nito, pinapayagan ng JSI ang pagtawag ng native methods nang walang serialisasyon ng mga mensahe at direktang pagpapasa ng mga reference sa C++ objects sa JS environment. Ayon sa datos ng React Native Team (2025), ang JSI ay nagbibigay ng hanggang 10 ulit na pagpapabilis ng interaksyon ng JS sa native code sa mga senaryo na may masinsinang pagpapalitan ng datos.
Mga Pangunahing Punto
JSI (JavaScript Interface) — ay isang C++ layer na nagbibigay sa JavaScript engine (Hermes, JavaScriptCore, V8) ng kakayahang direktang ma-access ang C++ objects, functions at memory. Hindi tulad ng Bridge na serialisado ang mga tawag sa JSON at ipinadala ang mga ito sa pamamagitan ng asinkronos na queue, pinapayagan ng JSI ang JS code na kasabay na tumawag ng C++ methods at makuha ang resulta kaagad.
Ang JSI ay ipinakilala sa React Native 0.64 bilang bahagi ng bagong arkitektura (New Architecture). Ang pangunahing layunin ay alisin ang bottleneck na dulot ng Bridge: bawat interaksyon sa pagitan ng JS at native code ay gumugol ng oras sa serialisasyon, deserialisasyon at paghahatid sa pamamagitan ng message queue. JSI nilulutas ang problemang ito sa pamamagitan ng pagbibigay sa JS engine ng direktang access sa C++ objects sa pamamagitan ng wrappers na nagpapatupad ng interface jsi::Value, jsi::Object at jsi::Function.
Ang JSI ay hindi kapalit ng Bridge na „isa-sa-isa” — ito ay isang fundamentally na ibang approach sa integration. Bridge ay gumana tulad ng isang mailbox: JS nagpadala ng mensahe, ito ay dumaan sa queue, ang native side ay nagproseso nito at nagpadala ng sagot. JSI ay gumagana tulad ng isang pointer: JS tumatanggap ng reference sa isang C++ object at maaaring tumawag ng mga method nito nang kasabay, tulad ng ordinaryong JS functions. Ito ang pangunahing pagkakaiba sa arkitektura ng interaksyon ng dalawang environment.
Ang pangangailangan para sa JSI ay lumitaw dahil sa mga limitasyon ng orihinal na Bridge na nilikha sa React Native 2015. Habang lumalaki ang kasikatan ng framework at naging mas kumplikado ang mga application, ang problema sa pagganap ay naging halata: bawat tawag sa native module ay nangangailangan ng hindi bababa sa 3–5 ms para sa serialisasyon. Para sa mga simpleng operasyon tulad ng pagbasa ng halaga ng sensor o pagkuha ng laki ng screen, ito ay katanggap-tanggap, ngunit para sa mga animation, pagtatrabaho sa graphics at streaming data processing — kritikal. Ang React Native team ay nagsimula ng trabaho sa bagong arkitektura noong 2019, at JSI ang naging pundasyon nito.
JSI ay idinisenyo bilang isang abstraction sa ibabaw ng JavaScript engines. Nagbibigay ito ng nagkakaisang C++ API na ipinatupad para sa bawat tiyak na engine: Hermes, JavaScriptCore (iOS), V8 (Android). Ito ay nangangahulugan na ang developer ay hindi kailangang mag-alala tungkol sa mga pagkakaiba sa pagitan ng mga engine — Fabric at TurboModules ay gumagana nang pareho kahit anong JS engine ang ginagamit.
Sa pundasyon ng JSI ay ang konsepto ng Host Objects — C++ objects na ini-export sa JS environment bilang native JS objects. Kapag ang JS code ay nag-access ng property o method ng naturang object, ang JSI ay humarang ng tawag at i-delegate ito sa katumbas na C++ method. Ito ay nangyayari nang kasabay, sa parehong thread, walang context switching at walang memory allocation para sa JSON string.
Bawat Host Object ay nagpapatupad ng interface jsi::HostObject na may mga method na get, set at getPropertyNames. Ang JS engine ay tumatawag sa mga method na ito sa bawat access sa properties ng object. Halimbawa, sa pagtawag ng NativeModule.someMethod() sa JS, JSI ay ginagawang C++ tawag ang tawag na ito ng katumbas na method ng Host Object. Ang ibinalik na halaga ay ipinapasa pabalik sa JS bilang jsi::Value — isang generalisadong uri na maaaring kumatawan ng numero, string, boolean value, object o undefined.
Isang mahalagang katangian ng JSI ay ang kawalan ng message queue. Bridge ay gumamit ng asinkronos na queue: JS nagpadala ng request, lumipat sa iba pang tasks, ang native side ay nagproseso ng request, at ang resulta ay bumalik sa pamamagitan ng callback. JSI ay gumagana nang kasabay: kung JS ay tumatawag ng method ng native module sa pamamagitan ng JSI, ang execution ng JS code ay naka-pause hanggang makuha ang resulta. Ito ay nagpapasimple ng logic (hindi kailangang maghintay ng callbacks) at nag-aalis ng race conditions, ngunit nangangailangan ng pag-iingat — mahahabang kasabay na tawag ay humaharang sa JS thread.
Ang mga value na ginawa sa pamamagitan ng JSI ay nabubuhay sa runtime environment ng JS engine at pinamamahalaan ng garbage collector. Kapag ang C++ code ay gumawa ng jsi::String o jsi::Object at ibinalik ito sa JS, ang environment ay awtomatikong namamahala ng memory. Kung gusto ng C++ code na panatilihin ang reference sa JS value sa pagitan ng mga tawag, ginagamit nito ang jsi::Value::getWeak() o global na jsi::Object::setProperty na may pag-iingat ng reference sa root object ng runtime. Ito ay pumipigil sa napaaga na pagtanggal ng garbage collector.
JSI ay hindi thread-safe bilang default. Lahat ng JSI method calls ay dapat magmula sa thread kung saan ang JS ay pinapatakbo (karaniwan ito ang JS thread ng React Native). Kung ang native module ay magsisimula ng background work sa isang hiwalay na thread, ang resulta ay dapat ibalik sa pamamagitan ng JS thread gamit ang runOnJS call mula sa TurboModules. Ang limitasyong ito ay ang presyo para sa synchronisidad at kawalan ng serialisasyon.
Ang pagkakaiba sa pagitan ng JSI at Bridge ay may pangunahing katangian at nakakaapekto sa lahat ng aspeto ng interaksyon ng JS sa native code. Bridge ay asinkronos, serialisado ang data sa JSON at gumamit ng message queue; JSI ay kasabay, gumagana sa native references at hindi nangangailangan ng serialisasyon.
| Parameter | Bridge | JSI |
|---|---|---|
| Model ng tawag | Asinkronos na queue | Kasabay na direktang tawag |
| Serialisasyon | JSON (serialisasyon + deserialisasyon) | Wala (direktang reference sa C++ objects) |
| Latency | 3–10 ms bawat tawag | 0.1–0.5 ms bawat tawag |
| Typing | Dinamiko (sa pamamagitan ng JSON) | Statiko (sa pamamagitan ng Codegen) |
| C++ integration | Sa pamamagitan lamang ng native modules (Java/ObjC) | Direkta, walang tagapamagitan |
| Thread | Hiwalay na native thread | JS thread (kasabay) |
Ayon sa datos ng React Native Team, ang migrasyon mula Bridge patungong JSI sa Facebook Marketplace app ay nagbawas ng startup time ng 35% at nagpababa ng memory consumption ng 20% dahil sa pag-aalis ng pagdodoble ng data sa pagitan ng JS at native side.
Bridge ay hindi „kamalian” — ito ay isang arkitektural na desisyon na makatwiran sa panahon ng paglikha ng React Native noong 2015. Ang native development para sa dalawang platform na may magkaibang wika ay nangangailangan ng unibersal na format ng pagpapalitan. JSON bilang serialisation format ay available sa lahat ng platform at pinayagan ang pag-iisa ng interaksyon. Ang problema ay lumitaw nang maglaon, nang ang React Native ay nagsimulang gamitin para sa mga kumplikadong application na may libu-libong tawag ng native modules bawat segundo.
React Native ay nagpapanatili ng backward compatibility: ang native modules na isinulat para sa Bridge ay patuloy na gumagana sa bagong arkitektura sa pamamagitan ng compatibility layer. Gayunpaman, para sa mga bagong module, inirerekomenda na agad na gamitin ang JSI sa pamamagitan ng TurboModules. Ang migrasyon ng umiiral na modules ay binubuo ng pagpapalit ng protocol ng interaksyon nang hindi binabago ang business logic ng module mismo.
JSI ay ang pangunahing layer kung saan itinayo ang lahat ng components ng bagong arkitektura ng React Native. Kung wala ang JSI, hindi maaaring gumana ang Fabric (bagong renderer) o TurboModules (optimisadong native modules). JSI ay nagbibigay ng nagkakaisang paraan ng interaksyon ng JS sa C++ sa lahat ng antas.
Fabric — ang bagong React Native renderer na gumagamit ng JSI para sa kasabay na access sa C++ UI representations. Sa lumang arkitektura, ang rendering ay dumaan sa Bridge: JS gumawa ng React elements, serialisado ang mga ito sa JSON, ipinadala sa pamamagitan ng Bridge, ang native side ay deserialisado at gumawa ng UI. Fabric sa pamamagitan ng JSI ay gumagawa ng C++ Shadow Tree objects nang direkta mula sa JS, kasabay na kinukuwenta ang Layout sa pamamagitan ng Yoga at ipinapasa ang handa na frames sa native renderer — walang kahit isang serialisasyon.
TurboModules — ay ang ebolusyon ng native modules ng React Native. Sa halip na irehistro ang module sa Bridge at tawagin ang mga method nito sa pamamagitan ng JSON, ang TurboModules ay gumagamit ng JSI para sa lazy loading at direktang pagtawag. Kapag ang JS code ay unang nag-access ng module, JSI ay gumagawa ng Host Object — ito ay naglo-load ng native module at nagbibigay ng mga method nito bilang C++ functions. Lazy loading ay nangangahulugan na ang module ay hindi kumokonsumo ng memory hanggang sa unang paggamit — ito ay lalong mahalaga sa mga application na may dose-dosenang native modules, marami sa mga ito ay ginagamit lamang sa mga tiyak na screen.
Para sa pagtatrabaho sa JSI sa bagong arkitektura, ginagamit ang Codegen — isang tool na gumagawa ng C++ wrappers mula sa JavaScript specifications. Ang developer ay naglalarawan ng interface ng native module sa TypeScript o Flow, at ang Codegen ay gumagawa ng C++ code na nagpapatupad ng JSI-compatible na Host Object. Ito ay nag-automate ng routine work at ginagarantiyahan na ang mga type sa JS at C++ side ay naka-synchronize.
Tingnan natin kung ano ang hitsura ng pagtatrabaho sa JSI sa praktika. Sa halimbawang ito, isang simpleng C++ class ang ginagawa na na-export sa JS sa pamamagitan ng JSI, at ang method nito ay tinatawag mula sa JavaScript code ng React Native.
// Calculator.h — C++ class header na accessible mula sa JS
class Calculator {
public:
double add(double a, double b) { return a + b; }
double multiply(double a, double b) { return a * b; }
};
Ang class na Calculator ay naglalaman ng dalawang aritmetikong method. Kailangan nating gawin itong accessible mula sa JS. Para dito, gumagawa tayo ng Host Object na bumabalot sa Calculator at nagbibigay ng mga method nito sa pamamagitan ng JSI.
// CalculatorHostObject.cpp — implementasyon ng JSI wrapper
class CalculatorHostObject : public jsi::HostObject {
private:
Calculator calc;
public:
jsi::Value get(jsi::Runtime& runtime,
const jsi::PropNameID& name) override {
auto propName = name.utf8(runtime);
if (propName == "add") {
return jsi::Function::createFromHostFunction(
runtime, name, 2,
[this](jsi::Runtime& runtime,
const jsi::Value& thisVal,
const jsi::Value* args,
size_t count) -> jsi::Value {
return jsi::Value(calc.add(
args[0].asNumber(),
args[1].asNumber()));
});
}
return jsi::Value::undefined();
}
};
Sa code na ito, ang method na get ay tinatawag sa tuwing ang JS ay nag-access ng property ng object. Kung ang pangalan ng property ay „addition”, isang C++ function ang ibinabalik na tumatanggap ng dalawang argumento mula sa JS at tumatawag ng calc.add(). Ang halaga ay ibinabalik bilang jsi::Value — JSI ay awtomatikong nagko-convert ng double sa JS number.
Pagkatapos irehistro ang Host Object sa JS environment, ang tawag ay parang ordinaryong JS function. Lahat ng type ay sinusuri sa phase ng code generation, na nag-aalis ng mga type mismatch error sa runtime.
// JavaScript — pagtawag ng C++ calculator sa pamamagitan ng JSI
import { Calculator } from 'react-native-calculator'
const result = Calculator.add(5, 3)
console.log(result) // 8 — kasabay, walang delay
const product = Calculator.multiply(4, 2.5)
console.log(product) // 10 — agarang resulta
Tandaan: ang resulta ay ibinabalik kaagad, walang Promise, walang await, walang callbacks. Ito ay isang kasabay na tawag, na imposible sa arkitektura ng Bridge. Para sa mga matagal na operasyon (pagbasa ng file, network request), dapat gumamit ng asinkronos na patterns — JSI ay hindi nag-aalis ng pangangailangan para sa background threads para sa mabibigat na gawain.
Sa praktika, karamihan ng mga developer ay hindi nagsusulat ng JSI Host Objects nang manu-mano — ang gawaing ito ay ginagawa ng Codegen, na gumagawa ng C++ wrappers batay sa TypeScript specifications. Gayunpaman, ang pag-unawa kung paano gumagana ang JSI sa ilalim ng hood ay kinakailangan para sa epektibong performance debugging at sa paggawa ng kumplikadong native modules na nangangailangan ng direktang access sa C++ libraries (Skia, FFmpeg, OpenCV).
Mga Madalas Itanong
Bridge ay gumagana nang asinkronos sa pamamagitan ng JSON serialisasyon at message queue — bawat tawag ay nangangailangan ng 3–10 ms para sa conversion ng data. JSI ay nagbibigay ng kasabay na direktang access sa C++ objects walang serialisasyon, na nagbabawas ng latency sa 0.1–0.5 ms. JSI ay sumusuporta rin sa pagpapasa ng mga reference sa objects, hindi ang kanilang mga kopya.
Oo, JSI ay nagbibigay ng nagkakaisang C++ API na ipinatupad para sa Hermes (default sa React Native), JavaScriptCore (iOS) at V8 (Android). Ang developer ay hindi kailangang sumulat ng ibang code para sa ibang engines — Fabric at TurboModules ay gumagana nang pareho sa lahat ng suportadong engines.
Oo, React Native ay nagbibigay ng backward compatibility layer. Ang native modules na isinulat para sa Bridge ay patuloy na gumagana sa bagong arkitektura. Gayunpaman, inirerekomenda na i-migrate ang mga ito sa TurboModules para makuha ang mga benepisyo ng JSI — lazy loading at kasabay na mga tawag.
Para sa pang-araw-araw na development — hindi. Ang TypeScript specifications ng native modules ay awtomatikong nai-compile sa C++ wrappers sa pamamagitan ng Codegen. Ang kaalaman sa C++ ay kinakailangan lamang kapag gumagawa ng sariling C++ libraries o kapag nagde-debug ng performance ng JSI sa runtime level.
JSI nilulutas ang tatlong pangunahing problema ng Bridge: mataas na latency dahil sa JSON serialisasyon, kakulangan ng kasabay na mga tawag, at kawalan ng kakayahang magpasa ng kumplikadong objects sa pamamagitan ng reference. JSI ay nagpapahintulot din ng direktang integration ng C++ libraries, nang walang Java o Objective-C layer.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din