React vs React Native: Key Architectural Differences Developers Need to Know
TLDR: React is a core JavaScript library for building user interfaces, while React Native is a specialized renderer that uses the same React core but targets native mobile platforms instead of the browser DOM, enabling "Learn Once, Write Anywhere" development.
When evaluating react vs react native for your next project, understanding their architectural relationship is crucial. Both technologies originate from the facebook/react repository and share the same component model, state management, and reconciliation algorithm. However, they diverge at the rendering layer, where React targets the browser DOM through react-dom, while React Native communicates with native platform UI primitives through its own renderer package.
Core Architecture: Shared Core, Different Renderers
At the heart of both technologies lies the react package, which defines components, hooks, and the reconciliation algorithm. The actual rendering logic lives in separate renderer packages that implement a host config interface consumed by the shared react-reconciler.
- React (Web): Uses
react-dom(orreact-dom/clientin modern APIs) as its renderer. This package translates React's fiber work into DOM mutations. - React Native: Uses
react-native-renderer(private to the repository) as its renderer. This package implements the host config that talks to the UIManager and the native bridge.
According to the source code in packages/react-native-renderer/src/ReactNativeRenderer.js, the renderer validates version compatibility between the core react package and itself, throwing a runtime error if they differ (lines 55-63).
Target Platforms and Host Configurations
The fundamental distinction in the react vs react native comparison lies in their target platforms and how they interact with them.
React (Web) targets the browser DOM. The host config in ReactDOMHostConfig provides DOM-specific methods like appendChild, removeChild, and setAttribute. These methods directly manipulate HTML elements in the browser.
React Native targets native platform UI primitives. Instead of DOM elements, it uses native components like View, Text, and Image. The host config in ReactFiberConfigNative.js and ReactFiberConfigFabric.js provides native-specific methods like createView, manageChildren, and dispatchCommand. These methods marshal commands across the native bridge to update actual native view objects on iOS or Android.
Rendering Models: Sync DOM vs Async Native Bridge
The rendering models differ significantly between the two platforms, affecting performance characteristics and developer experience.
React (Web) operates with synchronous layout in the browser. When React commits changes, the DOM updates immediately, and the browser's CSS layout engine recalculates styles synchronously.
React Native operates with an asynchronous bridge. Layout is performed by the native platform using Yoga, a cross-platform layout engine. The communication between JavaScript and native code happens asynchronously, which can introduce performance bottlenecks if not managed carefully.
However, React Native is evolving toward Fabric, the new renderer found in ReactFiberConfigFabric.js. Fabric switches to a persistent mode that clones trees instead of mutating them, and it enables synchronous communication capabilities that reduce the asynchronous bridge overhead. As noted in the react-reconciler/README.md, Fabric represents a significant architectural shift for React Native's rendering pipeline.
Version Compatibility and Development Tooling
When working with react vs react native, version management and tooling differ in important ways.
Version Compatibility:
- For React web apps, the core
reactversion must match thereact-domversion, enforced by npm peer dependencies. - For React Native, the core
reactversion must exactly match thereact-native-rendererversion. The source code inReactNativeRenderer.js(lines 55-63) includes a runtime check that throws an error if these versions diverge, preventing subtle reconciliation bugs.
Development Tooling:
- React (Web): React DevTools connect directly to the browser page via the
react-devtoolsbrowser extension. - React Native: DevTools embed a backend directly in the native app using
react-devtools-core, enabling debugging across the native bridge. This requires specific setup as detailed in thereact-devtoolsREADME.
Practical Code Comparison
Despite architectural differences, component logic remains identical between platforms, illustrating the "Learn Once, Write Anywhere" philosophy mentioned in the top-level README.
Web Implementation (React):
import { useState } from 'react';
import { createRoot } from 'react-dom/client';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Clicks: {count}
</button>
);
}
const root = createRoot(document.getElementById('root'));
root.render(<Counter />);
The core React library handles component state, while react-dom/client manages DOM rendering.
Mobile Implementation (React Native):
import { AppRegistry, View, Text, TouchableOpacity } from 'react-native';
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Clicks: {count}</Text>
<TouchableOpacity onPress={() => setCount(c => c + 1)}>
<Text style={{ fontSize: 20, color: 'blue' }}>Tap me</Text>
</TouchableOpacity>
</View>
);
}
AppRegistry.registerComponent('MyApp', () => Counter);
The same useState logic from react works unchanged, but AppRegistry from the react-native-renderer handles registration, and native components like View and Text replace DOM elements.
Summary
- React is the core library managing components, state, and reconciliation, while React Native is a specialized renderer built atop that core.
- React targets the browser DOM via
react-dom, using synchronous updates and CSS layout. - React Native targets native platform UI via
react-native-renderer, using an asynchronous bridge to communicate with native views, with the new Fabric renderer enabling persistent mode and synchronous capabilities. - Both platforms share identical component logic and hooks, but differ in styling (CSS vs JavaScript style objects) and development tooling (browser DevTools vs
react-devtools-core). - Version compatibility is strictly enforced:
reactmust matchreact-domfor web, andreactmust matchreact-native-rendererfor mobile, with runtime checks inReactNativeRenderer.js.
Frequently Asked Questions
Can I use React components directly in React Native?
No, you cannot use React web components directly in React Native. While the component logic and hooks from the react package are identical, React Native requires specific native UI primitives like View, Text, and Image from the react-native package instead of HTML elements. The styling system also differs, using JavaScript style objects rather than CSS. However, you can share business logic and custom hooks between platforms by isolating them from platform-specific rendering code.
What is the Fabric renderer in React Native?
Fabric is React Native's new rendering architecture found in ReactFiberConfigFabric.js. Unlike the legacy renderer that operates through an asynchronous bridge, Fabric implements a persistent mode that clones fiber trees rather than mutating them, similar to how React works on the web. This architecture enables synchronous communication between JavaScript and native code, reducing the asynchronous bridge overhead that traditionally caused performance bottlenecks. Fabric represents a significant shift toward aligning React Native's rendering model more closely with React DOM's capabilities while maintaining native platform integration.
How does styling differ between React and React Native?
React uses CSS stylesheets, inline styles, or CSS-in-JS solutions that the browser parses and applies to DOM elements. In contrast, React Native uses JavaScript style objects that are marshalled across the native bridge to the platform's native view layer. These style objects accept specific properties mapped to native layout engines (like Yoga) rather than CSS properties. The react-native-renderer validates these style objects at runtime, throwing errors for invalid properties as implemented in ReactNativeRenderer.js. This means you cannot use CSS media queries, pseudo-classes, or web-specific units like rem directly in React Native without abstraction libraries.
Do React and React Native versions need to match?
Yes, strict version matching is required between the core react package and its corresponding renderer. For web applications, react and react-dom must share the same version, enforced by npm peer dependencies. For React Native applications, the core react version must exactly match the react-native-renderer version. The source code in packages/react-native-renderer/src/ReactNativeRenderer.js (lines 55-63) includes a runtime validation that throws an error if these versions diverge, preventing subtle reconciliation bugs and ensuring fiber tree compatibility between the core library and the native platform renderer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →