# How Core React Native Components Are Implemented Natively: The View Manager Bridge

> Discover how React Native bridges JavaScript components to native UI objects using the view manager system. Learn about runtime instantiation and configuration of native views.

- Repository: [Meta/react-native](https://github.com/facebook/react-native)
- Tags: internals
- Published: 2026-02-25

---

**React Native bridges JavaScript component names like `View`, `Text`, and `ScrollView` to native UI objects through a platform-specific *view-manager* system that instantiates and configures concrete native views at runtime.**

In the `facebook/react-native` repository, core components are not JavaScript implementations but rather thin JavaScript wrappers that communicate with native code. When you render a `<View />` in your React application, the framework delegates creation and management to specialized native classes called view managers. These managers serve as the factory and configuration layer between the JavaScript thread and the host platform's UI toolkit.

## The View Manager Architecture

React Native uses a **view-manager pattern** to abstract platform differences while maintaining a consistent JavaScript API. Each core component maps to a manager class responsible for view instantiation, property application, layout calculation, and event dispatch.

| Platform | Core Abstraction | Concrete Example | Primary Responsibility |
|----------|------------------|------------------|------------------------|
| **iOS** | `RCTViewManager` (Objective-C) | `RCTViewManager`, `RCTTextViewManager`, `RCTScrollViewManager` | Registers a native `UIView` subclass and declares prop-to-setter mappings via `RCT_EXPORT_VIEW_PROPERTY` macros. |
| **Android** | `ViewManager<T extends View, C extends LayoutShadowNode>` (Java) | `BaseViewManager`, `ReactTextViewManager`, `AndroidViewManager` | Provides `View` instances and `ShadowNode` objects for layout, with property setters cached by `ViewManagersPropertyCache`. |

These managers are singletons registered with the **UIManager** module when the React Native bundle loads.

## Registration and Lookup

When your application initializes, the **UIManagerModule** (Android) or **RCTUIManager** (iOS) creates a **ViewManagerRegistry** that indexes all available native view managers by their JavaScript names.

In [`UIManagerModule.java`](https://github.com/facebook/react-native/blob/main/UIManagerModule.java), the registry iterates over compiled manager classes:

```java
// Simplified lookup flow in UIImplementation.java
ViewManager viewManager = mViewManagers.get(className);

```

On the JavaScript side, `requireNativeComponent('RCTView')` declares that the `View` component corresponds to the native manager named `RCTView`. This string must match constants like `RCTViewManager.REACT_CLASS` in the native implementation. When the React renderer requests a new node, the bridge resolves the appropriate manager from this registry and delegates view creation.

## Creating Native Views

View managers act as factories for concrete native UI elements. Each manager implements a specific factory method that returns a platform-native view instance.

**iOS** (`RCTViewManager.m`):

```objc
- (UIView *)view {
  return [RCTView new];  // Returns the concrete UIView subclass for <View />
}

```

**Android** ([`ViewManager.java`](https://github.com/facebook/react-native/blob/main/ViewManager.java)):

```java
public abstract class ViewManager<T extends View, C extends LayoutShadowNode> {
  public abstract T createViewInstance(ThemedReactContext reactContext);
}

```

Concrete implementations override these methods. For example, `ReactTextViewManager` overrides `createViewInstance` to return a `TextView`, while `RCTScrollViewManager` returns a specialized `RCTScrollView` on iOS.

## Property Mapping and Updates

Props passed from JavaScript are applied to native views through generated setter maps. Both platforms use reflection or code generation to build these mappings at runtime.

**iOS** uses macros to expose Objective-C setters:

```objc
RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
RCT_REMAP_VIEW_PROPERTY(customOpacity, alpha, CGFloat)

```

These macros expand into dictionary entries that the `RCTViewManager` uses to invoke the correct setter when JavaScript updates a prop.

**Android** uses annotations and caching. In [`ViewManagersPropertyCache.java`](https://github.com/facebook/react-native/blob/main/ViewManagersPropertyCache.java), the system scans for methods annotated with `@ReactProp` and builds a `Map<String, PropSetter>`:

```java
@ReactProp(name = "backgroundColor")
public void setBackgroundColor(View view, @Nullable Integer color) {
  view.setBackgroundColor(color != null ? color : Color.TRANSPARENT);
}

```

The `ViewManagerPropertyUpdater.updateProps` method uses this cache to batch-apply property changes to the native view efficiently.

## Layout and Shadow Nodes

Layout calculations occur outside the main UI thread using **Shadow Nodes**. Each view manager specifies a `LayoutShadowNode` subclass (e.g., `LayoutShadowNode` in [`ViewManager.java`](https://github.com/facebook/react-native/blob/main/ViewManager.java)) that represents the component in the Yoga layout engine.

The Yoga engine computes styles and measurements on these shadow nodes. Once layout completes, the framework commits the results to the native view through `onLayout` callbacks, ensuring the concrete `UIView` or Android `View` receives final dimensions and positions without blocking JavaScript execution.

## Event Wiring

Native-to-JavaScript events are declared using platform-specific mechanisms. **iOS** uses `RCT_EXPORT_VIEW_PROPERTY` with block types like `RCTBubblingEventBlock`, while **Android** uses event registration within the manager class. These declarations allow native gesture recognizers and view callbacks to dispatch events (such as `onPress` or `onChange`) across the bridge to JavaScript event handlers.

## Practical Mapping Examples

When you write JSX using core components, the following native implementations are invoked:

| JSX Element | Native Manager Class | Key Factory Method |
|-------------|---------------------|-------------------|
| `<View>` | `RCTViewManager` (iOS) / `BaseViewManager` (Android) | `- (UIView *)view` / `createViewInstance` |
| `<Text>` | `ReactTextViewManager` | Returns `RCTTextView` (iOS) or `ReactTextView` (Android) |
| `<ScrollView>` | `RCTScrollViewManager` | Returns `RCTScrollView` (iOS) or `ReactScrollView` (Android) |

## Summary

- **View Managers** are the native bridge implementation for every core React Native component, acting as factories and configuration agents.
- **Registration** occurs at bundle load time through `ViewManagerRegistry` (Android) and `RCTUIManager` (iOS), mapping JavaScript component names to native classes.
- **View Creation** happens through `- (UIView *)view` on iOS and `createViewInstance` on Android, returning concrete platform views.
- **Property Updates** flow through generated setter maps built by `RCT_EXPORT_VIEW_PROPERTY` macros (iOS) and `ViewManagersPropertyCache` with `@ReactProp` annotations (Android).
- **Layout** is computed on `LayoutShadowNode` instances using Yoga before being committed to native views.
- **Events** are wired through exported blocks (iOS) or explicit event methods (Android) to enable JavaScript callbacks.

## Frequently Asked Questions

### What is the difference between ViewManager and View in React Native?

A **ViewManager** is a singleton controller class (e.g., `RCTViewManager` or `ReactTextViewManager`) that knows how to create and configure native views. The **View** is the actual native UI instance (e.g., `UIView` on iOS or `android.view.View` on Android) that appears on screen. The manager creates the view, updates its properties, and handles its events, but the view itself is the rendered UI element.

### How does React Native know which native manager to use for a JavaScript component?

React Native uses string-based registration. When you import `View` from `react-native`, it internally calls `requireNativeComponent('RCTView')`. The string `'RCTView'` must match the manager's declared name (such as `RCTViewManager.REACT_CLASS` on iOS or the name returned by `getName()` in Android managers). The `UIManager` maintains a registry keyed by these strings to resolve the correct manager during the render phase.

### What are Shadow Nodes and why are they needed?

**Shadow Nodes** are lightweight representations of native views used for layout calculations. Because measuring and laying out UI can be expensive, React Native performs these calculations on shadow nodes (subclasses of `LayoutShadowNode`) in a background thread using the Yoga layout engine. This prevents blocking the JavaScript thread or main UI thread, and only the final layout results are passed to the actual native views.

### Where are the core view managers defined in the React Native source code?

Core view managers are located in platform-specific directories within the `packages/react-native` folder. On iOS, base implementations reside in `React/Views/RCTViewManager.m`, with specific components like text and scroll views in `React/Text/ReactTextViewManager.m` and `React/Views/ScrollView/RCTScrollViewManager.m`. On Android, the base class is [`ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java`](https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java), with concrete implementations such as [`BaseViewManager.java`](https://github.com/facebook/react-native/blob/main/BaseViewManager.java) and [`ReactTextViewManager.java`](https://github.com/facebook/react-native/blob/main/ReactTextViewManager.java) extending it.