# React vs React Native: Key Architectural Differences Developers Need to Know

> Discover the key architectural differences between React and React Native. Learn when to choose React vs React Native for your next project and unlock cross-platform development.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: architecture
- Published: 2026-02-16

---

**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` (or `react-dom/client` in 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`](https://github.com/facebook/react/blob/main/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`](https://github.com/facebook/react/blob/main/ReactFiberConfigNative.js) and [`ReactFiberConfigFabric.js`](https://github.com/facebook/react/blob/main/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`](https://github.com/facebook/react/blob/main/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`](https://github.com/facebook/react/blob/main/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 `react` version must match the `react-dom` version, enforced by npm peer dependencies.
- For React Native, the core `react` version must exactly match the `react-native-renderer` version. The source code in [`ReactNativeRenderer.js`](https://github.com/facebook/react/blob/main/ReactNativeRenderer.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-devtools` browser 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 the `react-devtools` README.

## 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):**

```javascript
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):**

```javascript
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: `react` must match `react-dom` for web, and `react` must match `react-native-renderer` for mobile, with runtime checks in [`ReactNativeRenderer.js`](https://github.com/facebook/react/blob/main/ReactNativeRenderer.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`](https://github.com/facebook/react/blob/main/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`](https://github.com/facebook/react/blob/main/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`](https://github.com/facebook/react/blob/main/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.