Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSI (JavaScript Interface) & JSC (JavaScript Core) Discussion #91

Open
kelset opened this issue Jan 24, 2019 · 74 comments
Open

JSI (JavaScript Interface) & JSC (JavaScript Core) Discussion #91

kelset opened this issue Jan 24, 2019 · 74 comments

Comments

@kelset
Copy link
Member

@kelset kelset commented Jan 24, 2019

What's the current status of JSI? Read here

Intro

With this issue I'd like to try and create a "one stop" for all the information available around the JavaScript Interface, the unified lightweight general purpose API for (theoretically) any JavaScript virtual machine.

Currently, the default Javascript Virtual Machine used by React Native is JavaScriptCore (JSC) - it is used in WebKit.

Terminology

  • Fabric: just the UI layer re-architecture, to take full advantage of concurrent React architecture. (dedicated issue)
  • TurboModules: re-architecture of NativeModules, also using JSI. (dedicated issue)
  • CodeGen: a tool to "automate" the compatibility between JS and native side. (dedicated issue)

TL;DR

From @axe-fb's blogpost, here's a temporary description of the JSI (please consider that this is not yet finalized, it may change in the future)

Instead of using the bridge for queuing messages, the new architecture allows us to directly "invoke" (think RPC) Java/ObjC methods.
An analogy would be how we call DOM methods from JavaScript in the browser. For example, in the statement var el = document.createElement('div'); the variable el holds a reference not to a JavaScript object, but to an object that was possibly instantiated in C++. When JavaScript calls el.setAttribute('width', 100), we end up synchronously invoking the setWidth method in C++ that changes the actual width of that element.
In React Native, we can similarly use the JavaScript interface to invoke methods on UI Views and Native Modules that are implemented in Java/ObjC.

Available Materials

At ReactConf 2018 @axe-fb did a talk about React Native's New Architecture, which also explains the 3 concepts above: JSI, Fabric, TurboModule.

Recently the JSC was upgraded for Android, you can check the commit here and the related issue in the main repo.

On twitter, @karanjthakkar did a thread detailing how he integrated the new JSC in the Skyscanner app.

In Q1 2019, @kelset wrote a high level explanation in a blogpost: https://formidable.com/blog/2019/jsi-jsc-part-2/ and did a talk about the whole rearchitecture in April 2019 at React Edinburgh.

Over on twitter, @ericlewis published a sample repo with @chrfalch to showcase how to use directly C++ in a RN app (thanks to the JSI): https://github.com/ericlewis/react-native-hostobject-demo

@kelset also did a more in-depth talk at React Advanced London in Oct 2019: youtube recording & slides.

@Jarred-Sumner published a quick benchmark difference between a lib and a reimplementation using JSI twitter.

Libraries implemented using JSI

Q&A

This is also a place for questions related to this effort and its direction.

@kelset kelset changed the title JSI (JavaScript Interface) Discussion JSI (JavaScript Interface) & JSC (JavaScript Core) Discussion Feb 19, 2019
@Eyesonly88
Copy link

@Eyesonly88 Eyesonly88 commented Mar 6, 2019

I have a couple of questions:

@Kudo
Copy link
Member

@Kudo Kudo commented Mar 6, 2019

@Eyesonly88

Why doesn't React Native use the same exact JSC for iOS and Android?
AFAIK, Android JSC !== iOS JSC (correct me if I'm wrong)

Even at the same version of JSC, the Android implementation is different to iOS.
So that Android JSC will always not equal to iOS.
Furthermore, different iOS versions have different JSCs.

Is it even possible to use something else other than JSC for iOS? AFAIK, even Chrome doesn't use V8 on iOS: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/zINHc4_dWhk

Yes, JSI brings a benefit for other platforms to use different JavaScript engine easier.
E.g. react-native-windows will use CharkaCore

BTW Chrome does not use v8 on iOS simply because they should follows App Store Review Guidelines

2.5.6 Apps that browse the web must use the appropriate WebKit framework and WebKit Javascript.

@Eyesonly88
Copy link

@Eyesonly88 Eyesonly88 commented Mar 6, 2019

@Kudo interesting, thanks for the reply.

Yeah, regarding V8 on iOS, that's what I was wondering about, even if RN provided a way to use other engines, we're stuck with JSC on iOS due to App Store rules.

@Pikaurd
Copy link

@Pikaurd Pikaurd commented Apr 4, 2019

@Eyesonly88 Please check @Kudo comment 2.5.6 Apps that browse the web must use the appropriate WebKit framework and WebKit Javascript. That focus "browse the web". Chrome is a web browser therefore google has to obey it.

@kelset kelset pinned this issue Apr 14, 2019
@sJJdGG
Copy link

@sJJdGG sJJdGG commented Apr 15, 2019

@Pikaurd @Eyesonly88 Yeah I also think @Kudo is right regarding usage of V8 and theoretically it should already be possible to submit V8-powered RN-based apps to app store review process and getting accepted considering JSI efforts on RN side and more importantly the almost new announced JIT-less V8 on V8 side.

But really eager to see a practical example that's accepted to app store.

To me biggest benefit of V8 (In addition to other common reasons) could be V8 snapshots that should help boosting startup times considering parsing javascript is a significant chunk of overall code execution time.

@Eyesonly88
Copy link

@Eyesonly88 Eyesonly88 commented Apr 15, 2019

@sJJdGG I'm happy to try it in one of my production apps, any guide on how would I go about doing that? (I'd do anything to improve startup time)

@sercand
Copy link

@sercand sercand commented Apr 16, 2019

@sJJdGG @Eyesonly88 ReactNative supports another bundle option which is ByteCode Bundle. It is not documented and I guess facebook uses it in their app. It must be be similar to V8 snapshots.

@aleclarson
Copy link

@aleclarson aleclarson commented Jun 2, 2019

Does this have any implications for WebAssembly interop with React Native?

@kirillpisarev
Copy link

@kirillpisarev kirillpisarev commented Jun 6, 2019

I still can't figure out how JSI will solve the problem with RN viewport size suspense in case of embedding RN within a native project? As i understand the flow now is like:

  1. init RN native
  2. init RN JS
  3. build JS shadow tree
  4. draw native

During all this time the viewport doesn't know the size of content that leads to UI problems.

So what will be changed to solve exactly this problem?

@kelset
Copy link
Member Author

@kelset kelset commented Jun 6, 2019

the viewport doesn't know the size of content that leads to UI problems

my understanding is that actually through JSI & Fabric, the viewport will know. But I may be wrong.

@kelset kelset unpinned this issue Jun 20, 2019
@oNaiPs
Copy link

@oNaiPs oNaiPs commented Aug 2, 2019

Hi guys, we have been working on a JSI implementation for node.
Idea is to be able to re-use JS<->C++ modules that work in both React Native and Node/Electron. We think JSI has a great potential to become an API for cross-runtime implementations.

We also worked on a C++ template system that allows us to define C++ classes that map easier to a JS object, without any codegen tools.

We would like to share our effort with the community, but would like some guidance on how we could do that, perhaps with some mentoring from people that is involved with JSI implementation.

Thanks

@akshetpandey
Copy link

@akshetpandey akshetpandey commented Sep 11, 2019

So I have some code using turbomodules but I understandably can't run it in remote debug mode since that runs with the remote chrome js engine. What is the workaround and what does the debug DX look like for JSI HostObjects and turbomodules?

@terrysahaidak
Copy link

@terrysahaidak terrysahaidak commented Sep 12, 2019

@akshetpandey I as remember, the current workaround is to have both JSI and the bridge and switching between them when you debugging.

When you're using JSI, your module available using global object, but once you've switched to a remote debugger, use NativeModules instead (if you have bindings).

You can check out @chrfalch's reanimated JSI example (might be outdated a bit): software-mansion/react-native-reanimated@master...chrfalch:jsi-methods

@TheSavior
Copy link

@TheSavior TheSavior commented Sep 12, 2019

When using JSI, we currently recommend using safari to debug the JSC instance running on device, or on Android if you are using Hermes, you can connect Chrome to the instance of Hermes running on device.

@terrysahaidak
Copy link

@terrysahaidak terrysahaidak commented Oct 21, 2019

Is there any article/example/docs on how to properly use JSI on Android? Maybe there is already module in current master which uses JSI on Android? I would appreciate any link.

@kelset
Copy link
Member Author

@kelset kelset commented Oct 21, 2019

@terrysahaidak I think that the closest thing to that atm is: ericlewis/react-native-hostobject-demo#4

@terrysahaidak
Copy link

@terrysahaidak terrysahaidak commented Oct 21, 2019

This looks cool and I've already seen it, but not quite sure how to trigger Java code from C++. By the way, does CodeGen is usable in any kind already?

@kelset
Copy link
Member Author

@kelset kelset commented Oct 21, 2019

I'm not sure about it being usable - afaik it's still under heavy development. But you can check it out here -> https://github.com/facebook/react-native/tree/master/packages/react-native-codegen

@chrfalch
Copy link

@chrfalch chrfalch commented Oct 21, 2019

@tomduncalf added a pull request to Eric and my repository showing how to add support for JSI on Android, don't know if that can be used?

ericlewis/react-native-hostobject-demo#4

@terrysahaidak
Copy link

@terrysahaidak terrysahaidak commented Oct 25, 2019

Here is my attempt to get JSI working on android. And yeah, JSI definitely works, but also JNI works as well! So yeah, we can call Java from JS right now:
https://github.com/terrysahaidak/host-object-test/blob/master/libs/android-jsi/test-jsi/src/main/cpp/TestJSIInstaller.cpp

grabbou added a commit to facebook/react-native that referenced this issue Jul 14, 2020
Summary:
The JavaScriptCore implementation of JSI [does not currently support array buffers](https://github.com/facebook/react-native/blob/master/ReactCommon/jsi/JSCRuntime.cpp#L925-L943). The comments in the code suggest the JSC version used by React Native does not work with array buffers, but this seems to be out of date since the current version of JSC used by React Native does indeed support array buffers. This change just enables array buffers in JSCRuntime.cpp.

NOTE: See react-native-community/discussions-and-proposals#91 (comment) for more background on this change.

## Changelog

[General] [Added] - Support for array buffers in the JavaScriptCore implementation of JSI
Pull Request resolved: #28961

Test Plan:
To test these changes, I just made some temporary changes to RNTester to use JSI to inject a test function into the JS runtime that reads from and writes to an array buffer, and call that function from the JS of the RNTester app (see ryantrem@28152ce).

For the JS side of this, specifically look at https://github.com/ryantrem/react-native/blob/28152ce3f4ae0fa906557415d106399b3f072118/RNTester/js/RNTesterApp.android.js#L13-L18

For the native side of this, specifically look at https://github.com/ryantrem/react-native/blob/28152ce3f4ae0fa906557415d106399b3f072118/RNTester/android/app/src/main/cpp/JSITest.cpp#L22-L38

Reviewed By: shergin

Differential Revision: D21717995

Pulled By: tmikov

fbshipit-source-id: 5788479bb33c24d01aa80fa7f509e0ff9dcefea6
@radiosilence
Copy link

@radiosilence radiosilence commented Oct 1, 2020

@sercand could you possibly share any more examples/info of how to do this? I'm interested in creating a iOS/Android WebSocket server that talks to React Native via JSI (currently I am using two different WS implementations in Java/Swift and it would be an interesting experiment to see if it is possible to have one rust codebase for it)!

@terrysahaidak
Copy link

@terrysahaidak terrysahaidak commented Oct 1, 2020

@radiosilence React Native Reanimated 2 uses JSI really intensively where you can access synchronously variables stored in C++ on JS thread and also call some functions on JS which are defined in C++ etc.

@sdc395biosite
Copy link

@sdc395biosite sdc395biosite commented Oct 1, 2020

@radiosilence @terrysahaidak I've just been poring over the Reanimated source code myself, trying to find the answer to the question I asked above. It seems I was right that callbacks to JS go via the bridge, and that something named CallbackInvokerHolder is involved. I've gotten as far as passing the holder into my JNI code but now I'm stuck as I've no idea how I'm supposed to extract the CallbackInvoker from the holder. Could someone join the dots for me? Reanimated seems to call getCallInvoker but, when I try, JNI throws a NoSuchMethodError. Thanks.

@chrfalch
Copy link

@chrfalch chrfalch commented Oct 2, 2020

@sdc395biosite I'm not entirely sure what you are trying to do here? You are talking about the bridge but want to call via JSI? Remember that JSI replaces the bridge - but you should be able to get a pointer to the current jsi:runtime through the bridge on startup. Just remember that when you are running the remote web executor (debugging) the runtime won't be available.

@terrysahaidak
Copy link

@terrysahaidak terrysahaidak commented Oct 2, 2020

@sdc395biosite it's not true, no bridge is used in Reanimated 2 sources. In this particular example, CallInvoker is used only to trigger asynchronously some JS function defined on JS Thread Context from the JS Context running on UI Thread (yeah, separate one).

Here is an example of running a function from JSI:

  1. Define a function in JS:
    https://github.com/software-mansion/react-native-reanimated/blob/028f00845558d2a63c15caef9e719dd838dc13a8/src/reanimated2/core.js#L46-L88
  2. Call JSI Native method to pass it to C++ (string representation of it)
    https://github.com/software-mansion/react-native-reanimated/blob/028f00845558d2a63c15caef9e719dd838dc13a8/src/reanimated2/NativeReanimated.js#L13-L15
  3. Define module spec for this native method:
    https://github.com/software-mansion/react-native-reanimated/blob/master/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp#L5-L13
  4. Define the native method itself:
    https://github.com/software-mansion/react-native-reanimated/blob/master/Common/cpp/NativeModules/NativeReanimatedModule.cpp#L96-L99
  5. Here is a part which stores the function in C++:
    https://github.com/software-mansion/react-native-reanimated/blob/master/Common/cpp/SharedItems/ShareableValue.cpp#L86-L91
  6. Call it with or without this:
    https://github.com/software-mansion/react-native-reanimated/blob/master/Common/cpp/SharedItems/MutableValue.cpp#L43-L46

Perhaps, you won't be able to call that function using JNI directly in Java/Kotlin, but I guess there is already some wrapper for this, take a look at fbjni and recent sources of React Native.

Update:
In this example, the module spec is used for TurboModules to work. The Codegen project will allow us to skip that part since all that code will be generated from the definition of the module written in Flow or TypeScript.

If you don't plan to use TurboModules right now, there is a way where you can do everything by yourself.
Here is an example of Reanimated 1 API "bridge" written in C++ with JSI, calling Java code using JNI I wrote almost a year ago when I had almost no knowledge and experience in C++:
https://github.com/terrysahaidak/reanimated-jsi/blob/master/jsi/android/ReanimatedJSI.cpp

Take a look at this get method. It's basically the same thing Codegen generates us for TurboModules:
https://github.com/terrysahaidak/reanimated-jsi/blob/master/jsi/android/ReanimatedJSI.cpp#L136

Also, lots of the code I wrote here is automated by Codegen and TurboModules such as resolving and storing references to Java classes

Here is an example of such generated file:
https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec-generated.cpp

As well as the generated specs for Java classes, for example:
https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeAccessibilityInfoSpec.java

@sdc395biosite
Copy link

@sdc395biosite sdc395biosite commented Oct 20, 2020

@terrysahaidak With much help from Reanimated 2, I now have a (nearly) working JSI implementation of my SQLite wrapper for RN. One last puzzle remains, and I'm hoping you'll be able to provide some insight.

When I resolve a Promise that I have created on the native side and returned to JS, my app does not respond until I interact with it. It is as if the JS thread, having just resolved the promise, fails to continue at the awaiting location. If I physically interact with the App's UI, JS springs to life and continues with the resolved value.

Is there something I need to do, in addition to resolving the promise, the get JS to continue?

@terrysahaidak
Copy link

@terrysahaidak terrysahaidak commented Oct 20, 2020

I guess @chrfalch can help here, he has a lot of experience with JSI. But I saw a mention of this problem already. Also, perhaps @shergin or @Kudo can help here.

@chrfalch
Copy link

@chrfalch chrfalch commented Oct 20, 2020

Could you provide some code snippets to describe what you are doing? Like some isolated code from both the js/native sides?

@mrousavy
Copy link

@mrousavy mrousavy commented Oct 20, 2020

I think it would be useful to many people if someone who knows their stuff could do a short article with code snippets showcasing JSI and TurboModules stuff, mainly because even the current official Native Modules docs aren't very detailed either.

@chrfalch
Copy link

@chrfalch chrfalch commented Oct 20, 2020

@mrousavy I've already written up a few articles about the topic:

What I believe should be clear is that JSI is not some magic sauce that will change how we write our React Native apps. JSI is an interface (based on the interface implemented by the JSC engine) that has been added to React Native so that the bridge can be removed by letting native code and JS interface directly. Our apps will eventually run quicker and more reliable with the new UI Architecture called Fabric that uses JSI for everything UI related.

The interface lets us call methods on the native side directly from JavaScript - but there is a lot of details and hidden stuff going on in how it is implemented in React Native (just look at how TurboModules are implemented, and how JS engines like JSC and Hermes are deployed and initialized).

To be able to provide greate developer experience, we are still somewhat limited to the async / await pattern when calling into native code from JS - this has to do with the fact that when debugging we need to run a remote JavaScript engine (Chrome) and interface using messages that are dispatched between our device / simulator and our development tools. (It is not possible to debug your code when enabling TurboModules AFAIK).

From looking at the source code in React Native there are still a lot of native modules that will continue to be in use when running in debug mode, and they all have corresponding TurboModules that are used in a production environment to speed things up at runtime, meaning that we'll still have to live with getting async callbacks from native when calling functions - the big difference will be that the bridge (and it's serialize / deserialize form of communication) can be dropped alltogether - giving us a lot of performance benefits in our release builds.

JSI has a public, stable and well-known API, but the documentation is lacking - leading to giving the React Native core developers a lot more flexibility in how they implement and use it in React Native - there are a lot of changes going on to ensure backwards compatibility and avoid any regressions.

My understanding is that JSI, Fabric and TurboModules will be released and made available for all React Native developers, and then there will be a migration path later for native modules to be moved over and republished as TurboModules. We've also seen evidence that Hermes will be made available on iOS (Build Hermes for iOS), and this will in turn make it possible to write a new set of debuggers and tools that eventually might lead to a better experience writing code that interfaces between JS and native in a well defined way.

I'm also a strong believer in using C++ as the language for writing native logic - and TurboModules and JSI is basically a C++ feature - making it easier for us to create cross platform logic on the native side as well as on the JS side.

Disclaimer: If I'm wrong in any of my assumptions or explanations in this post, please provide feedback and I'll try to correct it - I think it is important that the community knows what these concepts and technologies are for, and what they're not for.

@ryantrem
Copy link

@ryantrem ryantrem commented Oct 20, 2020

@bghgary and I just went through this for Babylon React Native with lots of help from @RSNara. Here are the things we learned that I think will be helpful to others:

  • When a promise is completed the promise "continuations" (functions passed to .then, or code after await) are "queued" via a call to setImmediate.
  • This immediates queue is flushed at different points in React Native execution, including pretty much any time there is activity across the classic bridge.
  • The immediates queue is also flushed by CallInvoker::invokeAsync after invoking the function you provide on the JS thread (see https://github.com/facebook/react-native/blob/ee3994530d4f76695d77c9a21a6b57429bac68aa/ReactCommon/cxxreact/Instance.cpp#L257-L296, and line 293 specifically).
  • When using JSI with React Native and doing async work on the C++ side that needs to later resolve a promise, you need to use CallInvoker::invokeAsync to properly get back on the JS thread and complete your promise so the above happens. If the immediates queue is not flushed, your pending promise continuations will not run until something else causes the immediates queue to be flushed (such as UI interactions, including tapping the screen).
  • With full TurboModule support, I think this will be trivial as it appears that TurboModules are passed the CallInvoker to their constructors.
  • Without full TurboModule support (the current state we are in with released version of React Native), it's a lot trickier, particularly on the android side. CallInvokerHolder is exposed on the Java side, and you can get the CallInvoker out of it, but:
    • CallInvokerHolder is built on top of fbjni (an Android C++/Java interop layer that simplifies JNI usage). libfbjni.so is included in React Native and available at runtime, but the headers that you need to program against it are not. They are in a Maven package that you can pull into your gradle project though.
    • The Java side of CallInvokerHolder expects to find a library named libturbomodulejsijni.so, which is not currently included in React Native (presumably in the future it will be with full TurboModule support). I believe Reanimated 2 builds the full TurboModule library and includes it in their package. For BabylonReactNative, we compile the absolute minimum (CallInvokerHolder.cpp) into a lib named libturbomodulejsijni.so and include it in our package. I assume if many packages use this workaround, they won't work together in one app since we'll end up with lots of libs named libturbomodulejsijni.so that will confict.
    • Once you have a libturbomodulejsijni.so (with at least CallInvokerHolder.cpp compiled into it) and fbjni, you can get the CallInvoker out of the CallInvokerHolder on the C++ side.

You can see the full set of changes we made to Babylon React Native to start using CallInvoker here: BabylonJS/BabylonReactNative#97

@kelset kelset pinned this issue Nov 18, 2020
@urbien
Copy link

@urbien urbien commented Dec 6, 2020

re-posting here a response on twitter from @fkgozali regarding TurboModules and Codegen in RN 0.64
https://twitter.com/fkgozali/status/1335004270991536129?s=21

As long as the modules are specific to your app, you can follow RNTester setup to enable it. All relevant code is already on master and will be included in 0.64. The setup is still rough and not very stable yet, but we’re planning to iterate further on this in early 2021.


edited by @kelset: to add text from tweet

@mrousavy
Copy link

@mrousavy mrousavy commented Mar 19, 2021

What's the current optimal solution to install HostFunctions into the jsi::Runtime? I have been simply installing them from my native module, but that lead to race conditions/threading issues because that was being invoked on the Native Module Thread, when it really should only be called on the JS thread.

I have tried to play around with JSIModule, JSIModulePackage, etc only to find out that that's not yet actually usable without creating a whole TurboModule. Also I have tried to dispatch to the JS Thread, but that didn't work because the HostFunctions aren't immediately installed when JS starts to execute.

I've created an issue for this here: facebook/react-native#31197, would love to hear some suggestions.

/cc @chrfalch @ryantrem @terrysahaidak @RSNara

@DEVfancybear

This comment has been hidden.

@hcminhit

This comment has been hidden.

@tranhiepqna

This comment has been hidden.

@fkgozali
Copy link

@fkgozali fkgozali commented May 11, 2021

Can you tell me JSI's current progress, how long will it take to release?

Could you clarify what you need with JSI? Did you just mean getting access to the VM via JSI abstraction? If so, that's already possible today. In fact the JSIExecutor C++ impl today is already accessing the VM using JSI for a while now. All JSI code is already in github: https://github.com/facebook/react-native/blob/master/ReactCommon/jsi/jsi/jsi.h

If you're trying to access the VM to do something with it, you can also try accessing with a logic you can add to your app like in RNTester:

iOS:

Android:

  • It's less ideal right now, but you can access the runtime via JSIModulePackage.
  • See the samples from facebook/react-native#31197 for now.

Note that while this work, you'll be responsible to ensure the access to the VM is safe.


Another alternative is to just write your own subclass of TurboModule C++ class and treat it like a "NativeModule", just in pure C++ (no Java/ObjC). Example: https://github.com/facebook/react-native/blob/dc80b2dcb52fadec6a573a9dd1824393f8c29fdc/ReactCommon/react/nativemodule/samples/ReactCommon/NativeSampleTurboCxxModuleSpecJSI.h#L19, which you can provide in your app like in RNTester: https://github.com/facebook/react-native/blob/master/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.mm#L25

Note: the latter requires TurboModule to be installed in your app, and we're working on creating a playbook for apps in OSS this year for clearer integration, as mentioned in #40 (comment).


For general updates regarding the new architecture, we're also preparing some writeup about it as mentioned in facebook/react-native#31469 (comment). Stay tuned.

@TheSavior
Copy link

@TheSavior TheSavior commented May 11, 2021

I think the tl;dr of @fkgozali's comment is that JSI has already shipped and React Native releases have been using it for a while. For app authors there is no user facing change, it is an implementation detail of React Native. The TurboModule system (that is still in progress) will take advantage of it more. If you are a module author and want to do custom things with it directly, the links Kevin provided might help you out.

@giangdinh

This comment has been minimized.

@gillpeacegood
Copy link

@gillpeacegood gillpeacegood commented May 21, 2021

Another alternative is to just write your own subclass of TurboModule C++ class and treat it like a "NativeModule", just in pure C++ (no Java/ObjC). Example: https://github.com/facebook/react-native/blob/dc80b2dcb52fadec6a573a9dd1824393f8c29fdc/ReactCommon/react/nativemodule/samples/ReactCommon/NativeSampleTurboCxxModuleSpecJSI.h#L19, which you can provide in your app like in RNTester: https://github.com/facebook/react-native/blob/master/packages/rn-tester/RNTester/RNTesterTurboModuleProvider.mm#L25

Note: the latter requires TurboModule to be installed in your app, and we're working on creating a playbook for apps in OSS this year for clearer integration, as mentioned in #40 (comment).

https://github.com/facebook/react-native/blob/dc80b2dcb52fadec6a573a9dd1824393f8c29fdc/ReactCommon/react/nativemodule/samples/ReactCommon/SampleTurboCxxModule.cpp

Is it possible for the getValueWithCallback & getValueWithPromise to be genuinely asynchronous and if so could you give any pointers as regards how to achieve that?

@kelset
Copy link
Member Author

@kelset kelset commented Jun 10, 2021

(with the help of @mrousavy I've added a list of libs that use JSI to the top post, so that you can use them as references)

@ammarahm-ed
Copy link

@ammarahm-ed ammarahm-ed commented Jun 13, 2021

react-native-mmkv-storage also uses JSI to communicate with native side. To make secure storage work in the library I have also accessed Java classes via C++ JNI. It means that any current module that uses the old bridge can easily update their library to use JSI instead keeping the functionality same by accessing java objects from JNI. This also helps remove the need to async/await for getting small data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet