After working with React Native for over a year, I've learned that understanding how it works isn't just nice to know it helps you write better code, fix bugs faster, and make your apps run smoother.

The Big Picture First
Before we look at each part, let's understand what React Native is trying to do. Regular native apps need different code for iOS and Android. React Native fixes this by letting you write most of your code in JavaScript while still showing real native components. But how does JavaScript talk to native code? That's where things get interesting.
Main Parts That Make It All Work
1) JavaScript Engine (Hermes)
Hermes is React Native's JavaScript engine. It's the part that runs all your JavaScript code.
What makes Hermes good:
Faster startup: Instead of reading JavaScript when the app starts, Hermes turns your code into a faster format during the build. This means your app opens quicker.
Uses less memory: Hermes needs less phone memory than other JavaScript engines, which is important since phones don't have unlimited memory.
Better cleanup: It cleans up unused memory better, so your app doesn't slow down or crash.
When you write const [count, setCount] = useState(0), Hermes is what actually creates that variable and manages it.
2) Fabric Renderer (The New Way)
Fabric is React Native's new system for showing things on screen. It replaced the old system called "Paper."
What Fabric does better:
Smoother animations: Unlike the old system, Fabric can update the screen right away, making animations look better.
Better error messages: When something breaks in your UI, Fabric gives clearer error messages and fixes problems better.
Faster communication: Less back-and-forth between JavaScript and native code means better speed.
Think of Fabric as the translator that takes your JSX components and turns them into real views that users can see and touch.
3) Turbo Modules
Turbo Modules are the new way React Native talks to native phone features. If you've used libraries like @react-native-async-storage/async-storage, you've used native modules.
What's better:
Only loads when needed: Modules only load when you actually use them, making your app smaller at startup.
Some things happen right away: Some operations don't need callbacks anymore, making code simpler.
Before Turbo Modules, calling a native function meant sending data and waiting for an answer. Now, some things can happen immediately.
4) JSI (JavaScript Interface)
JSI is the foundation that makes Turbo Modules and Fabric possible. It's a layer written in C++ that lets JavaScript and native code talk directly.
Why JSI is important:
Direct calls: JavaScript can call native functions directly without converting data back and forth.
Shared memory: Both sides can use the same memory space for some operations.
Better speed: Gets rid of the slow bridge system from before.
JSI is like having a direct phone line between JavaScript and native code, instead of sending letters through slow mail.
5) Codegen
Codegen automatically creates native code from your JavaScript definitions. It makes sure types match between JavaScript and native parts.
What it creates:
Native interface definitions
Type-safe connection code
Less boilerplate code to write
When you define a native module interface in JavaScript, Codegen creates all the native code needed to make it work safely.
6) Native UI Components
These are the real platform-specific components that show up on screen. When you use <View>, it becomes UIView on iOS and android.view.View on Android.
Key points:
Platform-specific: Each component maps to its native version
Same API: You write <Text> once, but it shows as UILabel or TextView depending on the platform
Fast: Since these are real native components, they work just like native apps
7) Threads
React Native uses multiple threads to keep your app smooth:
Main/UI Thread:
Handles user touches
Updates what you see on screen
Must never be blocked (this makes Android apps freeze)
JavaScript Thread:
Runs your React/JavaScript code
Handles state updates and app logic
Talks to native modules
Background Threads:
Handle network requests
Process images
Do heavy calculations
Understanding these threads is important for making fast apps. If you block the JavaScript thread with heavy work, your UI will freeze.
8) AppRegistry
AppRegistry is your app's starting point. It's where React Native learns about your main component.
AppRegistry.registerComponent('MyApp', () => App);
This line tells React Native: "When you need to show this app, start with the App component."
9) Metro Bundler
Metro is React Native's JavaScript bundler. It takes all your JavaScript files and creates one bundle that Hermes can run.
What Metro does:
Finds dependencies: Finds all the files your app needs
Converts code: Turns JSX, TypeScript, and modern JavaScript into code Hermes can run
Hot reloading: Lets you see changes instantly during development
Splits code: Can create multiple bundles for better performance
What Happens When You Tap a Button
Now for the fun part let's see exactly what happens when someone taps a button in your app. Let's say you have this button:
<TouchableOpacity onPress={() => setCount(count + 1)}>
<Text>Count: {count}</Text>
</TouchableOpacity>User's finger touches the screen
iOS/Android's touch system detects the touch
The native UI component gets the touch event
Native side figures out which React Native component should handle this touch
The native touch event gets turned into a format JavaScript can understand
This event data moves from the native thread to the JavaScript thread
With JSI, this happens much faster than the old system
React Native's event system gets the touch event
The event moves through the component tree (just like in web React)
Your onPress function gets called: () => setCount(count + 1)
setCount(count + 1) triggers React's state update
React schedules a re-render of your component
The new state value (count + 1) gets calculated
React creates a new virtual version of your component tree
It compares this new tree with the old tree
React finds that the Text component's content changed from "Count: 0" to "Count: 1"
React creates instructions for what needs to change in the UI
These instructions go from JavaScript thread back to the native side
With Fabric, this communication is faster and can happen right away
The native UI system gets the update instructions
iOS/Android updates the real native text component
The new text "Count: 1" appears on screen
The whole process usually takes just a few milliseconds
User sees the updated count and feels the app is fast
Any animations also get processed during this cycle
Understanding this flow helps explain common performance problems:
Blocking the JavaScript thread with heavy work means steps 3-6 can't happen, making your app freeze.
Too much back-and-forth in the old system created slowdowns between steps 2 and 7.
Big component trees slow down step 5 (finding changes), which is why good component design matters.
React Native's design has gotten much better, especially with the new architecture (Fabric + Turbo Modules + JSI). The main improvements focus on:
Less overhead between JavaScript and native code
More things can happen right away for better user experience
Better type safety across the JavaScript-native boundary
Better performance through better rendering and module loading
As React Native developers, understanding how things work helps us make better choices, fix bugs faster, and write faster code. The platform keeps getting better, but these core ideas give you a solid foundation for building great mobile apps.
The next time you see a smooth animation or a fast button press in your app, you'll know exactly what's happening behind the scenes and that's really useful knowledge to have.
0
4
0