Understanding the Difference Between React and React Native: A Deep Dive into Renderers and Host Configurations

React is the core JavaScript library that defines the component model and reconciliation algorithm, while React Native is a platform-specific renderer that uses the same React core to translate components into native mobile UI primitives rather than browser DOM elements.

The distinction between React (often called React JS) and React Native lies not in the component logic or hooks API, but in the rendering layer that translates your JavaScript code into visible user interface elements. According to the facebook/react source code, both platforms share an identical core engine and reconciler, differing only in their host configurations—the platform-specific adapters that create actual UI instances.

React Core: The Platform-Agnostic Engine

At the heart of both ecosystems is the React core, located in packages/react/src/React.js and re-exported via packages/react/index.js. This layer defines the component API (createElement, hooks like useState), element creation, and the fiber scheduler. Crucially, the core library does not know how to render UI—it only describes what the UI should look like through a virtual element tree.

The heavy lifting is performed by the reconciler, implemented in packages/react-reconciler/src/ReactFiberReconciler.js. This platform-agnostic engine walks the React element tree, computes the minimal set of changes (diffing), and schedules updates. However, the reconciler delegates all actual UI operations to a host-specific renderer via a pattern called the host config.

React JS (React DOM): The Web Renderer

When building for the browser, React DOM serves as the official renderer. Its entry point resides in packages/react-dom/src/client/ReactDOMClient.js, where createRoot() initiates a root fiber node attached to a DOM container. The renderer translates React elements into browser DOM nodes, attaches event listeners, and manages the HTML document tree.

The bridge between the reconciler and the browser is the host config, defined in packages/react-dom/src/client/ReactDOMHostConfig.js. This file implements platform-specific operations like createInstance (to create DOM elements), appendChild, and commitMount. Because this configuration is isolated from the core reconciler, React can target the web without altering the shared reconciliation algorithm.

// Web example using React DOM
import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button onClick={() => setCount(c => c + 1)}>
      Clicked {count} times
    </button>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Counter />);

Key implementation detail: The <button> element above becomes a real HTMLButtonElement through the host config's createInstance method, which invokes document.createElement('button') under the hood.

React Native: The Native Mobile Renderer

React Native replaces the DOM renderer with a bridge to native platform UI. Its renderer entry point is packages/react-native-renderer/src/ReactNativeRenderer.js, which communicates with iOS/Android native view managers to create actual platform-native objects (e.g., UIView on iOS, android.view.View on Android).

Like React DOM, React Native uses the same reconciler but swaps the host config in packages/react-native-renderer/src/ReactNativeHostConfig.js. Instead of document.createElement, this config creates native view objects and serializes layout calculations over the React Native bridge to the platform's UI layer.

// Native example using React Native
import React, { useState } from 'react';
import { Text, TouchableOpacity, View, StyleSheet } from 'react-native';

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={() => setCount(c => c + 1)} style={styles.button}>
        <Text style={styles.text}>Clicked {count} times</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  button: { padding: 12, backgroundColor: '#007AFF', borderRadius: 4 },
  text: { color: '#fff', fontSize: 16 }
});

Key implementation detail: Here, <View> and <TouchableOpacity> are not DOM elements but instructions sent to the native side via the bridge, where corresponding native view objects are instantiated and updated by the native host config.

Sharing Logic Across Platforms

Because both renderers utilize the identical reconciler and core hooks API (packages/react-reconciler/src/ReactFiberReconciler.js), business logic and state management can be shared between web and native applications. Only the UI primitive imports differ—import from 'react' works everywhere, while import from 'react-dom' and import from 'react-native' are renderer-specific.

// shared/useCounter.js - works in both React DOM and React Native
import { useState } from 'react';

export function useCounter(initial = 0) {
  const [count, setCount] = useState(initial);
  const increment = () => setCount(c => c + 1);
  return { count, increment };
}

The useState hook executes identically in both environments because it lives in the shared React core. Only when the reconciler calls the host config's createInstance or appendChild methods does the execution path diverge toward DOM nodes or native views.

Summary

Frequently Asked Questions

Is React Native the same as React JS?

No, React Native is not the same as React JS, though they share the same core engine. React JS refers to the combination of the React core library and the React DOM renderer for web browsers. React Native is a separate renderer that uses the same React core but translates components into native mobile platform UI elements rather than DOM nodes, utilizing packages/react-native-renderer/src/ReactNativeRenderer.js instead of the DOM client.

Can you use the same components in React and React Native?

You cannot use the same JSX components verbatim because React DOM relies on HTML primitives (like <div> and <span>) while React Native requires specific native primitives (like <View> and <Text>). However, you can share the logic and custom hooks between platforms because both use the same core React library (packages/react/index.js) and reconciler (packages/react-reconciler/src/ReactFiberReconciler.js). Only the UI primitive imports must change based on the target renderer.

What is the host config in React?

The host config is the interface between the platform-agnostic reconciler and the platform-specific UI layer. It defines methods like createInstance, appendInitialChild, and commitMount that instruct the reconciler how to create and manipulate actual UI elements. React DOM implements this in packages/react-dom/src/client/ReactDOMHostConfig.js for browser DOM operations, while React Native implements it in packages/react-native-renderer/src/ReactNativeHostConfig.js for native view creation.

Which should I choose for mobile development: React JS or React Native?

Choose React Native if you need to build applications that render actual native platform UI components and have access to native device APIs. Choose React JS (with React DOM) if you are building mobile web applications or progressive web apps (PWAs) that run in the browser. React Native provides native performance and platform-native look-and-feel, whereas React JS in a mobile browser offers easier deployment via URLs but limited native hardware access.

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:

Share the following with your agent to get started:
curl -s https://instagit.com/install.md

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client