And why its architecture is awesome, at a top level.
When writing React Native apps, we build native UIs. And that’s the key point, we create UIView instances just like we would have with platform specific languages:
My first assumption on this framework was something like:
They probably create an AST from the JS code and transform it to make it run on multiple devices.
But what currently exist are compilers that target their own specific platform. For example, we have compilers that accept Java / Kotlin code and target Android platform, or Obj-C / Swift targeting iOS platform. It exists many compilers for different languages and targets. They do their job well because they have been designed to create optimised artefacts for them.
React Native is built in such a way that it uses existing compilers:
It’s built with a really opened architecture that allows the code to be run, not only on mobile devices, but also on other supports:
It can also be used with other frameworks:
- Weex, a React Native port of Vuejs.
- a custom Angular renderer that allows to run ng apps in devices, with React Native.
So how did the team build such a framework, that is platform and framework agnostic, by using the existing tools & compilers?
Multiple realms interacting, nothing else
Let’s take a step back and look at the big picture of React Native.
The bridge is the concept that provides a way for bidirectional and asynchronous communications between these two universes. What’s important here is that they are completely written in different technologies, but they are able to communicate.
Remember your backend side
Let’s remember when we were coding distributed backend applications with multi-service communications.
How do we manage communication between two services that are completely different at a language/platform level ?
We used interoperable languages, such as JSON or XML, and we relied on asynchronous protocols such as AMQP (or any other).
If we want these two services to communicate, we rely on a message queue. The first service pushes some commands inside the queue and the other one has to execute these commands when possible.
In React Native, the bridge endorses the message broker role, handling asynchronous commands between the two different worlds.
It offers multiple possibilities:
- since it’s asynchronous, it’s non blocking, and therefore allows for smooth view management on the screen (~6O fps is the React Native golden goal)
- since it’s decoupled and based on interoperable languages, it’s wide open to other frameworks and rendering systems provided that they respect the React Native bridge command interface
The more the bridge’s language is ubiquitous and universal, the more the possibilities are… and it is indeed!
The bridge implementation
The bridge is built in C/C++ and thus, can be run on multiple platforms, OS etc…
The native side
The communication on the native side is “the easiest” part.
Let’s begin with the iOS platform. Since Obj-C is an extension of the C language, it can communicate with it natively. This way, exchanges between the bridge and the Swift / Obj-C world are easy and natural.
On Android, we need to rely on the Java Native Interface to dialog with the bridge.
Here’s an old but really awesome and deep post explaining how the bridge is implemented on iOS by Tadeu Zagallo.
Let me know if you have further questions regarding React Native internals. I’ll try to provide all that I know on the topic.