What is JSI?
JavaScript Interface (JSI) is Facebook's engine-agnostic interface for calling native code from a JavaScript runtime. It is effectively the Foreign Function Interface (FFI) for React Native.
Documentation for it is scarce. The main resource is the code comments in <jsi/jsi.h>. I myself mostly learned it by following Ammar Ahmed's Getting Started guide and by studying community libraries like Marc Rousavy's react-native-vision-camera.
How does it integrate with React Native?
The below description will soon go out of date, as Facebook are actively rearchitecting things. But I expect that the main broad concepts will remain the same, even if the exact implementation changes a little.
The React Native runtime executes JSI functionality through a JSIExecutor, and JavaScript functionality through its superclass, JSExecutor. The JSIExecutor is abstract, however, and so has to be implemented for each specific engine, e.g. HermesExecutor and JSCExecutor.
JSI has been implemented for many different engines, so you can see various different ways to integrate it:
- Hermes (by Meta)
- JavaScriptCore (originally by Meta, but later moved to community ownership)
- V8 (independently by Microsoft and Expo; see Kudo Chien's talk on the latter)
- QuickJS (by Microsoft, for a hackathon)
- Chakra (by Microsoft, for use in React Native Windows, as Chakra is included with Windows)
- Duktape (by Semmy Purewal)
Using Hermes as an example: At some point, React Native calls HermesExecutorFactory::createJSExecutor to make a HermesExecutor, which is basically just a subclass of JSIExecutor that holds a reference to a HermesRuntime and returns that reference in its implementation of JSExecutor::getRuntimeTargetDelegate.