Part Two: JSI and JSC
First announced in 2018, the React Native re-architecture is a massive effort Facebook undertook to address some long-standing issues of this cross-platform mobile solution.
In this series we will give an overview of the main elements that comprise React Native’s new structure. We will avoid showing code, to keep this explanation as accessible as possible, and will share our excitement regarding this new implementation.
In this second post we will dive into how React Native consumes the code you write, and how the re-architecture changes it.
Because of the nature of JavaScript, the React Native team has to rely on an engine to interpret it so that it can run in a native mobile application. In the current architecture, the team chose to use JavaScriptCore (JSC) directly, as per Apple’s iOS guidelines rule “to use the appropriate WebKit framework and WebKit JavaScript” (JSC is the one used by WebKit).
To enhance this element, (second block of the current React Native architecture) they decided to properly separate the bundled and minified JavaScript produced from the written code, and the engine that would “digest it”. This was made possible by introducing a third element between the two, unequivocally called JavaScript Interface (JSI).
The JSI is not part of React Native per se—it is a unified, lightweight, general-purpose layer for (theoretically) any JavaScript engine. But, when inserted in the broader puzzle of the new architecture, it allows for a few truly important improvements.
The first one is fairly intuitive—potentially, the JSC could now be swapped out more easily for other engines (or newer versions of the JSC, as recently happened in RN 0.59). Other options you may know are ChakraCore by Microsoft and V8 by Google.
The second improvement—arguably the cornerstone of the whole re-architecture—is that “by using JSI, JavaScript can hold reference to C++ Host Objects and invoke methods on them.” This means that, finally, we are tackling the core issue explained in the previous article: the two realms of JavaScript and Native will be really aware of each other, and there won’t be any need to serialize to JSON the messages to pass across, removing all congestion on the bridge (we’ll explore this more in the next article).
This is a very exciting change because C++ has long been one of the few ways to share code between Android and iOS without relying on JavaScript; Android’s native code is written in C\C++ (Java and Kotlin gets “translated down” via a Java Native Interface) and similarly iOS supports it by default (Objective-C is none other than a strict superset of C).
So this re-architecture step of React Native both enables massive changes to the current structure and opens the door to write more C++ for your apps, also enabling easier brownfield approaches.
If we were to replace the second block of the architecture with its new counterpart (you can find the full graph in the first article), the change would look like this:
This concludes the second part of our exploration of the re-architecture. Over the next few weeks we’ll release more posts diving into the other blocks. In the meantime, remember to share this article with your fellow developers or reach out for follow-up questions over on Twitter (DMs are open).
As you can imagine, these changes open the door to many more improvements in the next block, and we hope they spark excitement regarding how they will impact your codebases, without requiring any rewrites.
All aboard the hype train!
Other installments: