Is React and React Native the same thing? If you ever wonder what’s the difference between these two technologies, you are not alone.
In modern software development, React and React Native emerged as two powerful tools to build applications. Whether you’re a beginner or an experienced developer, knowing these tools will help you create incredible applications more easily.
Both React and React Native adhere to the same core principles of React but serve different purposes. Understanding the differences between these two powerful technologies helps developers and businesses choose the right tool for the job.
This blog dives deep into the comparison between React vs. React Native, exploring how they work under the hood, and comparing their key features, use cases, and the pros and cons of each technology.
What is React?
React, also known as React.js is a javascript library that is used to build dynamic and interactive user interfaces. Developed by Meta, this open-source library is heavily used in the industry to build scalable web applications.
React is declarative in nature. That means we only tell it what to do, not how to do it, and everything else is handled by it.
React followed component-based architecture. Components are easily manageable, reusable blocks that construct the whole UI. This approach makes it easier to integrate with already existing code, which accelerates and simplifies the development process.
React makes use of Virtual DOM which optimizes the UI updates and rendering. This makes React an excellent choice for front-end development.
For outstanding React JS development services, companies like Vivasoft, recognized as one of the best React JS development companies in the USA, provide top-notch solutions tailored to various needs.
How does React work?
We all know that in React, we can build components with JSX and render them on the web using React DOM. But what happens behind the scenes?
How does React manage to do all the DOM operations quickly and efficiently while providing a great development environment for developers?
Let’s briefly go through the basic concepts that make React what it is.
Before jumping into the more complex topic, let’s make sure we understand the core of React – elements and components.
In plain and simple terms components can be thought of as javascript functions (for the functional components) or classes (for the class components) that return JSX.
I am sure we are all familiar with this piece of code. This react functional component renders “Hello, <name>” on the screen.
const Greetings = (props) => {
return Hello, {props.name}
;
};
Now for us, this is just a react component that returns a react element. But for react, the return value is an object. If we call this function and check the console console.log(Greetings({ name: “Pranto” })), we will see a similar object like this:
{
'$$typeof': Symbol(react.element),
type: 'h1',
key: null,
ref: null,
props: { children: [ 'Hello, ', 'Pranto' ] },
_owner: null,
_store: {}
}
Now here two things happen behind the scenes –
- The JSX return from the component gets converted to React.createElement() function calls. This function helps us to create a react element that can be understood by the browser. The function call looks like this:
//createElement(type, props, ...children)
React.createElement("h1", null, "Hello, ", props.name);
- The function call returns an object like the above.
So basically react components are functions or classes that take input as props and return output as an element tree.
Now the question is how the component is being called. So when we import the component in our react app, react calls the component behind the scenes.
If it is a functional component, react calls it directly and if it is a class component, react calls it render method. To keep track of components’ internal state and lifecycle methods, react creates an instance of that component and manages the mounting and unmounting of components.
Next move to the Reconciliation part. From the above discussion, we can say that all react does is create trees of elements. This process is very fast as elements are just plain javascript objects.
React then recursively build the tree from the top. React keeps these trees of elements in memory called virtual DOM.
React internally maintains a virtual DOM tree so that it can control the rendering process because updating the DOM is expensive and can affect performance as the browser has to go through the whole repainting process and recalculate the element’s size and position to update the DOM as well as update the whole DOM tree even for a small update.
Updating virtual DOM is much faster and more efficient than actual DOM as it does not require extensive browser operations.
But now the question is how to react and then update the real DOM efficiently using virtual DOM and synchronize both the real and virtual DOM.
At the initial render, react has to pass the whole tree to the real DOM. But when there is any state change that can produce a different return value or element, react quickly and build another tree of elements.
Now react has to compare both the new tree in the virtual DOM and the old tree in the real DOM. It will be extremely inefficient to re-render the whole tree.
That’s where react magic happens. React compares both the trees and finds the smallest number of operations needed to update the real DOM.
React can do that using an algorithm called Diffing algorithm. The algorithm uses a heuristic approach and for this, the algorithm has to make two assumptions –
- Two different types of elements will produce two different trees.
- For the list of elements, all children should have unique keys to identify them uniquely.
So this is reconciliation. The process of updating the virtual DOM uses the diffing algorithm to find the minimal number of changes to efficiently update the real DOM to reflect the changes.
Now let’s talk about rendering. When we try to create a react web application, we can see that we also have to install react-dom as a peer dependency.
This is called a renderer. Similarly, for mobile platforms, react uses the React Native renderer, for 3D works react has the React Three Fiber renderer.
React itself is just a UI library that can produce components and elements, it is not specific to any platform. The renderer mostly does the heavy lifting. It begins the reconciliation process, generates the tree of elements, and inserts it in the appropriate position.
What is React Native?
React Native is an open-source framework developed by Meta and is used to build cross-platform mobile applications.
That means we can build apps both for Android and iOS at the same time with a unified codebase.
React Native uses native components, compared to other hybrid frameworks, therefore the performance and visual appeal of React Native apps are comparable to those of native apps.
React Native provides the best of both worlds – the convenience of JavaScript and the performance of native.
How does React Native work?
Let’s now dive into the world of React Native. What happens when you run your React Native app?
Like React, in react native, we also write Javascript/Typescript code and create components. Similar to the browser with a javascript engine to execute Javascript code, JS code is also executed via javascript engines (like Javascript Core) in React native.
The JS code is bundled together during the production build and the native code for specific operative systems is kept separately.
The react native code mainly works over three separate threads:
- The Javascript thread: The JS bundle that we generate during the build process is executed in this thread via the javascript engine. This thread handles all the business logic and functionality of the application.
- The Native/ UI thread: This thread runs the native modules (like Bluetooth, GPS, Camera, etc) as well as handles the rendering of the UI, and user interactions like pressing or gesture events.
- Shadow thread: This thread handles the layout, size, and position of the elements that have to be rendered by the UI thread. For this React Native uses a layout engine called Yoga. Yoga ensures consistent UI layout across different platforms.
As Javascript and native modules can not directly interact with each other, so if they want to communicate, they need some form of communication channel. In the earlier architecture of React Native, the communication between the JS thread and the UI thread is carried by a bridge.
The bridge serializes the data sent by the JS thread and then deserializes it on the UI thread. Although this data serialization process ensures data compatibility, but at the same time introduces additional overheads.
The bridge architecture has other issues like it only supports asynchronous communication which leads to delays. These delays make user interaction unresponsive during complex tasks, and animations less smooth.
So to overcome these issues, React Native deprecated the old bridge architecture and adopted a new architecture that introduced several new concepts.
Javascript Interface (JSI)
JSI is a lightweight general-purpose layer that is written in C++. JSI is decoupled from the javascript engine, So we can use any javascript engine whereas, in the old bridge architecture, we had to use the javascript core engine.
As JSI is written in C++, it can hold the reference of the host object. Because of this, javascript can invoke native APIs directly which ensures synchronous seamless commission between the JS thread and the Native thread.
Fabric
Fabric is the new rendering system for React Native. In the old architecture, the renderer first created a shadow tree from the React element tree.
Then the tree is passed to Yoga (layout engine) to calculate the position and size of the element in the UI. Then this shadow tree is transformed into a host-specific tree with native features.
Now for this React Native has to maintain two hierarchies which can create inconsistencies between JS thread and Native thread resulting in lag or frame drops.
With the new fabric rendering system, we can prioritize the tasks that can be executed synchronously (like user gestures or scrolling) in threads as it leverages the JSI. This process reduces the number of steps involved render a particular element on UI. Now a common immutable shadow tree is shared among the threads and each thread keeps a reference to that shared tree. This whole thing maintains synchronization among threads and reduces the overhead cost of back-and-forth communication resulting in better performance.
Turbo Module
But with the current architecture, the turbo module allows the javascript code to hold a reference to those native modules and lazily load them whenever needed. This significantly improves the performance of the app.
Codegen
Javascript is a dynamically typed language whereas the JSI written in C++ is a statically typed language.
We need an interface to ensure smooth communication between the Javascript and C++ worlds. Here comes Codegen for the rescue. Codegen is a tool that generates code that binds the javascript code to native code as well as works as a static type checker.
Codegen generates the native code for JSI that will be eventually used by Fabric and Turbo Modules. With Codegen, we don’t have to deal with native code.
Codegen generates native code in build time instead of run time. This ensures type safety, reduces manual errors, and speeds up development.
React vs React Native
Although both react and react native share the same core APIs of react as well as follow core principles of react (components, state, props, etc), they have distinct differences. Even if you are a React expert, you have to spend a good amount of time knowing the fundamentals of mobile development.
Platform Dependency
Perhaps the most obvious difference between these technologies is the platform they are targeting.
React is used for building web applications whereas React Native is designed for mobile devices. Web applications run on browsers. On the other hand, React native utilizes mobile hardware to run mobile applications.
In recent years, mobile hardware has reached a new peak. It can do things that the browsers can not do. Things like push notifications, in-app purchases, haptics, and gestures give an extra edge to mobile applications over web applications.
Rendering
React uses HTML to render things on the web. React native has to rely on host native API to render things on mobile.
Layout and Styling
React uses CSS or CSS-in-js libraries (like styled-components, emotion) to achieve styling for the components. In React Native, the core concepts of CSS are translated over but the support is limited.
The CSS engine is pretty basic compared to the browser. It only supports common properties like borders, margins, paddings, typography, backgrounds, etc.
There are no fancy CSS properties like calc(), pseudo-elements (:: before,:: after), keyframes, filter, clip-path, etc. React Native mainly uses a styling system that resembles the CSS but is just a JavaScript object under the hood.
In React we have things like flexbox, grid, float, position properties to create layouts. But things are not quite the same in the mobile world. React native uses a layout engine called Yoga to layout the UI.
But Yoga is limited to only flexbox and relative/absolute positioning. No support for grid or any other display properties. So you come from a web development background, the choice of layout designing is very limited for you in mobile application development.
Navigation
React-navigation is considered the standard library to implement navigation in mobile applications which is fairly different from react-router; the standard routing solution for react applications.
So as a developer, you have to think differently about designing complex navigation for different platforms.
Libraries
Many libraries are supported by both React and React Native since they both conform to the fundamental concepts of React. Although some libraries need some configuration to handle platform-specific APIs.
For example, react-hook-form uses <form> tag in React. However as there is no HTML in React Native, the library needs a wrapper (<Controller />) to handle form in a mobile platform. Similarly, on the web, we can easily upload files using native HTML input (<input type=” file” />).
But to handle file upload in react native, we have to rely on third-party libraries (react-native-image-picker, react-native-document-picker.)
As we already know from the above discussion React and React Native both have different styling systems, and UI libraries for the web will not make any sense for mobile.
Optimization
React uses hooks like useMemo, and useCallback as well as various other optimization techniques (code splitting, compressing images and other static files, dynamic imports, tree shaking, etc) to make the application more performant and efficient.
In React Native, along with these React optimizations, developers also have to think about hardware and architecture optimization for mobile applications.
Mobile hardware varies a lot and the architecture is completely different for Android and iOS. Lack of optimization can hamper the performance of the application as most of the application heavily depends on the device hardware performance which makes mobile development more challenging.
On mobile, the stakes are significantly higher for development teams as well as product teams; App Store reviews are seriously impacted by crashes and poor performance.
Development
React applications are built using HTML, CSS, and Javascript and use tools like Webpack, Eslint, Babel, etc. Whereas React Native uses native components that eventually translate into native elements. For example, the “View” component is translated to “ViewGroup” in Android and “UIView” in iOS.
While there are some similarities between React Native and React application development tools (such as the Chrome debugger), there are also some significant differences (such as metro bundler, debugging AsyncStorage, and more).
Breakpoints and console logging are two common approaches used by developers; other ways vary depending on the situation (e.g., knowing when to restart the packager vs reinstalling the app on the device).
During the development, we used a browser to observe the changes we made during development. Some browsers may not have some APIs or CSS properties, but we always have alternative ways to support that.
For mobile applications, we need a simulator or real device to test features. It is worth noting that for iOS simulation, you will need a Mac. Also, the Android emulators or iOS simulators don’t have many device-specific features like – GPS, Bluetooth, etc.
Testing
Testing in React Native shares similarities with React, such as using Jest and React Testing Library for unit testing with similar syntax. However, developers need to mock native dependencies specific to React Native.
For end-to-end testing, traditional tools like Selenium, Cypress, and Playwright are incompatible as these tools are DOM-based and there is no DOM in React Native. Instead, Detox or Appium are necessary for effective mobile testing.
Despite automation efforts, manual testing remains essential, particularly for configuring TestFlight and Play Store setups, which can be complex. Platforms like EAS can simplify these processes, enhancing testing efficiency in React Native development.
Release
Developers can easily deploy react applications to the web or solve bugs/issues on the fly without any kind of restrictions.
Publishing or updating an app in the Play Store or app store is a whole different ball game. Both stores have some rules and regulations that the application should have to follow.
Going through these processes can be quite cumbersome and time-consuming which may lead to slower development.
Is React and React Native the same thing?
Well, this question is quite obvious to ask. Both React and React Native adhere to the same core React principles.
A good amount of React knowledge can be utilized in React Native.Having a good understanding of React and Javascript can simplify the learning curve of React Native which allows the web developer to transition into mobile development seamlessly.
Component-based architecture, props handling, state management, HTTP request handling – all the concepts are similar in both the React and React Native worlds.
But React and React Native are not interchangeable. Both have different purposes and use cases. The difference will be prominent when the device layer comes into play.
For example, there is no window object in the mobile realm. So to store data in the client device, we use local storage in React whereas AsyncStorage in React Native.
Use Cases
Both React and React Native have a huge ecosystem and vast community support. React js is highly suitable for building single-page applications (SPA), complex user interfaces, and interactive web applications.
React can also be used to develop progressive web apps(PWA) which provide an app-like experience.
React Native is an ideal choice for building apps that require rapid development as well as the performance, look, and feel of native apps. React native uses native platform-specific APIs that provide all the functionality that a native app has to offer with just a unified codebase.
Pros and Cons of React and React Native
Of course, both technologies have some drawbacks along with the usefulness they provide. So before choosing what path to take, we must analyze the pros and cons of both. React is a go-to solution for building complex, scalable web solutions.
Along with the great developer experience it provides, the library is supported by a huge community of developers. But at the end of the day, React is just a library that depends on many third-party libraries to enhance its capabilities.
At the same time, even though the React app can be optimized for mobile usage following mobile-friendly techniques (like responsive design, PWA) it still lacks mobile-specific features like GPS, Bluetooth, etc).
The key advantages of React Native include near-native speed, access to native device functions like the camera and GPS, and cross-platform development with a single codebase that significantly reduces development time and resources.
Although the learning curve of React Native is steeper than React as the developer has to learn native-specific concepts to work with native APIs. Having good knowledge of native development is a plus point for achieving advanced customization for React Native apps.
Wrap up
Both React and React Native are highly capable technologies in their respective domains. Having a rich ecosystem and vast community of developers makes them a prominent choice for companies and developers.
Vivasoft, as a React JS development company, excels in leveraging these technologies to build robust applications.
The choice between them is based on the specific requirements of your project, the level of experience of your development team, and long-term maintenance factors.