home / skills / microck / ordinary-claude-skills / react-native-expo

react-native-expo skill

/skills_all/react-native-expo

This skill guides you through building and migrating Expo apps with New Architecture, React 19 changes, and Swift template updates.

npx playbooks add skill microck/ordinary-claude-skills --skill react-native-expo

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
24.9 KB
---
name: react-native-expo
description: |
  Build React Native 0.76+ apps with Expo SDK 52. Covers mandatory New Architecture (0.82+), React 19 changes (propTypes/forwardRef removal), new CSS (display: contents, mixBlendMode, outline), Swift iOS template, and DevTools migration.

  Use when: building Expo apps, migrating to New Architecture, or troubleshooting "Fabric component not found", "propTypes not a function", "TurboModule not registered", or Swift AppDelegate errors.
---

# React Native Expo (0.76-0.82+ / SDK 52+)

**Status**: Production Ready
**Last Updated**: 2025-11-22
**Dependencies**: Node.js 18+, Expo CLI
**Latest Versions**: [email protected], expo@~52.0.0, [email protected]

---

## Quick Start (15 Minutes)

### 1. Create New Expo Project (RN 0.76+)

```bash
# Create new Expo app with React Native 0.76+
npx create-expo-app@latest my-app

cd my-app

# Install latest dependencies
npx expo install react-native@latest expo@latest
```

**Why this matters:**
- Expo SDK 52+ uses React Native 0.76+ with New Architecture enabled by default
- New Architecture is **mandatory** in React Native 0.82+ (cannot be disabled)
- Hermes is the only supported JavaScript engine (JSC removed from Expo Go)

### 2. Verify New Architecture is Enabled

```bash
# Check if New Architecture is enabled (should be true by default)
npx expo config --type introspect | grep newArchEnabled
```

**CRITICAL:**
- React Native 0.82+ **requires** New Architecture - legacy architecture completely removed
- If migrating from 0.75 or earlier, upgrade to 0.76-0.81 first to use the interop layer
- Never try to disable New Architecture in 0.82+ (build will fail)

### 3. Start Development Server

```bash
# Start Expo dev server
npx expo start

# Press 'i' for iOS simulator
# Press 'a' for Android emulator
# Press 'j' to open React Native DevTools (NOT Chrome debugger!)
```

**CRITICAL:**
- Old Chrome debugger removed in 0.79 - use React Native DevTools instead
- Metro terminal no longer streams `console.log()` - use DevTools Console
- Keyboard shortcuts 'a'/'i' work in CLI, not Metro terminal

---

## Critical Breaking Changes (Dec 2024+)

### šŸ”“ New Architecture Mandatory (0.82+)

**What Changed:**
- **0.76-0.81**: New Architecture default, legacy frozen (no new features)
- **0.82+**: Legacy Architecture **completely removed** from codebase

**Impact:**
```bash
# This will FAIL in 0.82+:
# gradle.properties (Android)
newArchEnabled=false  # āŒ Ignored, build fails

# iOS
RCT_NEW_ARCH_ENABLED=0  # āŒ Ignored, build fails
```

**Migration Path:**
1. Upgrade to 0.76-0.81 first (if on 0.75 or earlier)
2. Test with New Architecture enabled
3. Fix incompatible dependencies (Redux, i18n, CodePush)
4. Then upgrade to 0.82+

### šŸ”“ propTypes Removed (React 19 / RN 0.78+)

**What Changed:**
React 19 removed `propTypes` completely. No runtime validation, no warnings - silently ignored.

**Before (Old Code):**
```typescript
import PropTypes from 'prop-types';

function MyComponent({ name, age }) {
  return <Text>{name} is {age}</Text>;
}

MyComponent.propTypes = {  // āŒ Silently ignored in React 19
  name: PropTypes.string.isRequired,
  age: PropTypes.number
};
```

**After (Use TypeScript):**
```typescript
type MyComponentProps = {
  name: string;
  age?: number;
};

function MyComponent({ name, age }: MyComponentProps) {
  return <Text>{name} is {age}</Text>;
}
```

**Migration:**
```bash
# Use React 19 codemod to remove propTypes
npx @codemod/react-19 upgrade
```

### šŸ”“ forwardRef Deprecated (React 19)

**What Changed:**
`forwardRef` no longer needed - pass `ref` as a regular prop.

**Before (Old Code):**
```typescript
import { forwardRef } from 'react';

const MyInput = forwardRef((props, ref) => {  // āŒ Deprecated
  return <TextInput ref={ref} {...props} />;
});
```

**After (React 19):**
```typescript
function MyInput({ ref, ...props }) {  // āœ… ref is a regular prop
  return <TextInput ref={ref} {...props} />;
}
```

### šŸ”“ Swift iOS Template Default (0.77+)

**What Changed:**
New projects use Swift `AppDelegate.swift` instead of Objective-C `AppDelegate.mm`.

**Old Structure:**
```
ios/MyApp/
ā”œā”€ā”€ main.m              # āŒ Removed
ā”œā”€ā”€ AppDelegate.h       # āŒ Removed
└── AppDelegate.mm      # āŒ Removed
```

**New Structure:**
```swift
// ios/MyApp/AppDelegate.swift āœ…
import UIKit
import React

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(_ application: UIApplication, ...) -> Bool {
    // App initialization
    return true
  }
}
```

**Migration (0.76 → 0.77):**
When upgrading existing projects, you **MUST** add this line:
```swift
// Add to AppDelegate.swift during migration
import React
import ReactCoreModules

RCTAppDependencyProvider.sharedInstance()  // āš ļø CRITICAL: Must add this!
```

**Source:** [React Native 0.77 Release Notes](https://reactnative.dev/blog/2025/01/14/release-0.77)

### šŸ”“ Metro Log Forwarding Removed (0.77+)

**What Changed:**
Metro terminal no longer streams `console.log()` output.

**Before (0.76):**
```bash
# console.log() appeared in Metro terminal
$ npx expo start
> LOG  Hello from app!  # āœ… Appeared here
```

**After (0.77+):**
```bash
# console.log() does NOT appear in Metro terminal
$ npx expo start
# (no logs shown)  # āŒ Removed

# Workaround (temporary, will be removed):
$ npx expo start --client-logs  # Shows logs, deprecated
```

**Solution:**
Use React Native DevTools Console instead (press 'j' in CLI).

**Source:** [React Native 0.77 Release Notes](https://reactnative.dev/blog/2025/01/14/release-0.77)

### šŸ”“ Chrome Debugger Removed (0.79+)

**What Changed:**
Old Chrome debugger (`chrome://inspect`) removed. Use React Native DevTools instead.

**Old Method (Removed):**
```bash
# āŒ This no longer works:
# Open Dev Menu → "Debug" → Chrome DevTools opens
```

**New Method (0.76+):**
```bash
# Press 'j' in CLI or Dev Menu → "Open React Native DevTools"
# āœ… Uses Chrome DevTools Protocol (CDP)
# āœ… Reliable breakpoints, watch values, stack inspection
# āœ… JS Console (replaces Metro logs)
```

**Limitations:**
- Third-party extensions not yet supported (Redux DevTools, etc.)
- Network inspector coming in 0.83 (late 2025)

**Source:** [React Native 0.79 Release Notes](https://reactnative.dev/blog/2025/04/release-0.79)

### šŸ”“ JSC Engine Moved to Community (0.79+)

**What Changed:**
JavaScriptCore (JSC) moved out of React Native core, Hermes is default.

**Before (0.78):**
- Both Hermes and JSC bundled
- JSC available in Expo Go

**After (0.79+):**
```json
// If you still need JSC (rare):
{
  "dependencies": {
    "@react-native-community/javascriptcore": "^1.0.0"
  }
}
```

**Expo Go:**
- JSC completely removed from Expo Go (SDK 52+)
- Hermes only

**Note:** JSC will eventually be removed entirely from React Native.

### šŸ”“ Deep Imports Deprecated (0.80+)

**What Changed:**
Importing from internal paths will break.

**Before (Old Code):**
```typescript
// āŒ Deep imports deprecated
import Button from 'react-native/Libraries/Components/Button';
import Platform from 'react-native/Libraries/Utilities/Platform';
```

**After:**
```typescript
// āœ… Import only from 'react-native'
import { Button, Platform } from 'react-native';
```

**Source:** [React Native 0.80 Release Notes](https://reactnative.dev/blog/2025/06/release-0.80)

---

## New Features (Post-Dec 2024)

### CSS Properties (0.77+ New Architecture Only)

React Native now supports many CSS properties previously only available on web:

#### 1. `display: contents`

Makes an element "invisible" but keeps its children in the layout:

```typescript
<View style={{ display: 'contents' }}>
  {/* This View disappears, but Text still renders */}
  <Text>I'm still here!</Text>
</View>
```

**Use case:** Wrapper components that shouldn't affect layout.

#### 2. `boxSizing`

Control how width/height are calculated:

```typescript
// Default: padding/border inside box
<View style={{
  boxSizing: 'border-box',  // Default
  width: 100,
  padding: 10,
  borderWidth: 2
  // Total width: 100 (padding/border inside)
}} />

// Content-box: padding/border outside
<View style={{
  boxSizing: 'content-box',
  width: 100,
  padding: 10,
  borderWidth: 2
  // Total width: 124 (100 + 20 padding + 4 border)
}} />
```

#### 3. `mixBlendMode` + `isolation`

Blend layers like Photoshop:

```typescript
<View style={{ backgroundColor: 'red' }}>
  <View style={{
    mixBlendMode: 'multiply',  // 16 modes available
    backgroundColor: 'blue'
    // Result: purple (red Ɨ blue)
  }} />
</View>

// Prevent unwanted blending:
<View style={{ isolation: 'isolate' }}>
  {/* Blending contained within this view */}
</View>
```

**Available modes:** `multiply`, `screen`, `overlay`, `darken`, `lighten`, `color-dodge`, `color-burn`, `hard-light`, `soft-light`, `difference`, `exclusion`, `hue`, `saturation`, `color`, `luminosity`

#### 4. `outline` Properties

Visual outline that doesn't affect layout (unlike `border`):

```typescript
<View style={{
  outlineWidth: 2,
  outlineStyle: 'solid',      // solid | dashed | dotted
  outlineColor: 'blue',
  outlineOffset: 4,           // Space between element and outline
  outlineSpread: 2            // Expand outline beyond offset
}} />
```

**Key difference:** Outline doesn't change element size or trigger layout recalculations.

**Source:** [React Native 0.77 Release Notes](https://reactnative.dev/blog/2025/01/14/release-0.77)

### Android XML Drawables (0.78+)

Use native Android vector drawables (XML) as Image sources:

```typescript
// Load XML drawable at build time
import MyIcon from './assets/my_icon.xml';

<Image
  source={MyIcon}
  style={{ width: 40, height: 40 }}
/>

// Or with require:
<Image
  source={require('./assets/my_icon.xml')}
  style={{ width: 40, height: 40 }}
/>
```

**Benefits:**
- Scalable vector graphics (resolution-independent)
- Smaller APK size vs PNG
- Off-thread decoding (better performance)

**Constraints:**
- Build-time resources only (no network loading)
- Android only (iOS still uses SF Symbols or PNG)

**Source:** [React Native 0.78 Release Notes](https://reactnative.dev/blog/2025/02/release-0.78)

### React 19 New Hooks

#### 1. `useActionState` (replaces form patterns)

```typescript
import { useActionState } from 'react';

function MyForm() {
  const [state, submitAction, isPending] = useActionState(
    async (prevState, formData) => {
      // Async form submission
      const result = await api.submit(formData);
      return result;
    },
    { message: '' }  // Initial state
  );

  return (
    <form action={submitAction}>
      <TextInput name="email" />
      <Button disabled={isPending}>
        {isPending ? 'Submitting...' : 'Submit'}
      </Button>
      {state.message && <Text>{state.message}</Text>}
    </form>
  );
}
```

#### 2. `useOptimistic` (optimistic UI updates)

```typescript
import { useOptimistic } from 'react';

function LikeButton({ postId, initialLikes }) {
  const [optimisticLikes, addOptimisticLike] = useOptimistic(
    initialLikes,
    (currentLikes, amount) => currentLikes + amount
  );

  async function handleLike() {
    addOptimisticLike(1);  // Update UI immediately
    await api.like(postId);  // Then update server
  }

  return (
    <Button onPress={handleLike}>
      ā¤ļø {optimisticLikes}
    </Button>
  );
}
```

#### 3. `use` (read promises/contexts during render)

```typescript
import { use } from 'react';

function UserProfile({ userPromise }) {
  // Read promise directly during render (suspends if pending)
  const user = use(userPromise);

  return <Text>{user.name}</Text>;
}
```

**Source:** [React 19 Upgrade Guide](https://react.dev/blog/2024/04/25/react-19-upgrade-guide)

### React Native DevTools (0.76+)

**Access:**
- Press `j` in CLI
- Or open Dev Menu → "Open React Native DevTools"

**Features:**
- āœ… Reliable breakpoints (unlike old Chrome debugger)
- āœ… Watch values, call stack inspection
- āœ… JS Console (replaces Metro logs)
- āœ… Chrome DevTools Protocol (CDP) based
- ā³ Network inspector (coming in 0.83)
- āŒ Third-party extensions not yet supported

**Source:** [React Native DevTools Announcement](https://reactnative.dev/blog/2024/10/release-0.76#react-native-devtools)

---

## Known Issues Prevention

This skill prevents **12** documented issues:

### Issue #1: propTypes Silently Ignored
**Error:** No error - `propTypes` just doesn't work
**Source:** [React 19 Upgrade Guide](https://react.dev/blog/2024/04/25/react-19-upgrade-guide)
**Why It Happens:** React 19 removed runtime propTypes validation
**Prevention:** Use TypeScript instead, run `npx @codemod/react-19 upgrade` to remove

### Issue #2: forwardRef Deprecated Warning
**Error:** `Warning: forwardRef is deprecated`
**Source:** [React 19 Upgrade Guide](https://react.dev/blog/2024/04/25/react-19-upgrade-guide)
**Why It Happens:** React 19 allows `ref` as a regular prop
**Prevention:** Remove `forwardRef` wrapper, pass `ref` as prop directly

### Issue #3: New Architecture Cannot Be Disabled (0.82+)
**Error:** Build fails with `newArchEnabled=false`
**Source:** [React Native 0.82 Release Notes](https://reactnative.dev/blog/2025/10/release-0.82)
**Why It Happens:** Legacy architecture completely removed from codebase
**Prevention:** Migrate to New Architecture before upgrading to 0.82+

### Issue #4: "Fabric component descriptor not found"
**Error:** `Fabric component descriptor provider not found for component`
**Source:** [New Architecture Migration Guide](https://reactnative.dev/docs/new-architecture-intro)
**Why It Happens:** Component not compatible with New Architecture (Fabric)
**Prevention:** Update library to New Architecture version, or use interop layer (0.76-0.81)

### Issue #5: "TurboModule not registered"
**Error:** `TurboModule '[ModuleName]' not found`
**Source:** [New Architecture Migration Guide](https://reactnative.dev/docs/new-architecture-intro)
**Why It Happens:** Native module needs New Architecture support (TurboModules)
**Prevention:** Update library to support TurboModules, or use interop layer (0.76-0.81)

### Issue #6: Swift AppDelegate Missing RCTAppDependencyProvider
**Error:** `RCTAppDependencyProvider not found`
**Source:** [React Native 0.77 Release Notes](https://reactnative.dev/blog/2025/01/14/release-0.77)
**Why It Happens:** When migrating from Objective-C to Swift template
**Prevention:** Add `RCTAppDependencyProvider.sharedInstance()` to AppDelegate.swift

### Issue #7: Metro Logs Not Appearing
**Error:** `console.log()` doesn't show in terminal
**Source:** [React Native 0.77 Release Notes](https://reactnative.dev/blog/2025/01/14/release-0.77)
**Why It Happens:** Metro log forwarding removed in 0.77
**Prevention:** Use React Native DevTools Console (press 'j'), or `--client-logs` flag (temporary)

### Issue #8: Chrome Debugger Not Working
**Error:** Chrome DevTools doesn't connect
**Source:** [React Native 0.79 Release Notes](https://reactnative.dev/blog/2025/04/release-0.79)
**Why It Happens:** Old Chrome debugger removed in 0.79
**Prevention:** Use React Native DevTools instead (press 'j')

### Issue #9: Deep Import Errors
**Error:** `Module not found: react-native/Libraries/...`
**Source:** [React Native 0.80 Release Notes](https://reactnative.dev/blog/2025/06/release-0.80)
**Why It Happens:** Internal paths deprecated, strict API enforced
**Prevention:** Import only from `'react-native'`, not deep paths

### Issue #10: Redux Store Crashes with New Architecture
**Error:** App crashes on Redux store creation
**Source:** [Redux Toolkit Migration Guide](https://redux-toolkit.js.org/usage/usage-guide)
**Why It Happens:** Old `redux` + `redux-thunk` incompatible with New Architecture
**Prevention:** Use Redux Toolkit (`@reduxjs/toolkit`) instead

### Issue #11: i18n-js Unreliable with New Architecture
**Error:** Translations not updating, or app crashes
**Source:** Community reports (GitHub issues)
**Why It Happens:** `i18n-js` not fully compatible with New Architecture
**Prevention:** Use `react-i18next` instead

### Issue #12: CodePush Crashes on Android
**Error:** Android crashes looking for bundle named `null`
**Source:** [CodePush GitHub Issues](https://github.com/microsoft/react-native-code-push/issues)
**Why It Happens:** Known incompatibility with New Architecture
**Prevention:** Avoid CodePush with New Architecture, or wait for official support

---

## Migration Guide: 0.72-0.75 → 0.82+

### Step 1: Upgrade to Interop Layer First (0.76-0.81)

**Why:** Can't skip directly to 0.82 if using legacy architecture - you'll lose the interop layer.

```bash
# Check current version
npx react-native --version

# Upgrade to 0.81 first (last version with interop layer)
npm install [email protected]
npx expo install --fix
```

### Step 2: Enable New Architecture (if not already)

```bash
# Android (gradle.properties)
newArchEnabled=true

# iOS
RCT_NEW_ARCH_ENABLED=1 bundle exec pod install

# Rebuild
npm run ios
npm run android
```

### Step 3: Fix Incompatible Dependencies

**Common incompatibilities:**

```bash
# Replace Redux with Redux Toolkit
npm uninstall redux redux-thunk
npm install @reduxjs/toolkit react-redux

# Replace i18n-js with react-i18next
npm uninstall i18n-js
npm install react-i18next i18next

# Update React Navigation (if old version)
npm install @react-navigation/native@latest
```

### Step 4: Test Thoroughly

```bash
# Run on both platforms
npm run ios
npm run android

# Test all features:
# - Navigation
# - State management (Redux)
# - API calls
# - Deep linking
# - Push notifications
```

### Step 5: Migrate to React 19 (if upgrading to 0.78+)

```bash
# Run React 19 codemod
npx @codemod/react-19 upgrade

# Manually verify:
# - Remove all propTypes declarations
# - Remove forwardRef wrappers
# - Update to new hooks (useActionState, useOptimistic)
```

### Step 6: Upgrade to 0.82+

```bash
# Only after testing with New Architecture enabled!
npm install [email protected]
npx expo install --fix

# Rebuild
npm run ios
npm run android
```

### Step 7: Migrate iOS to Swift (if new project)

New projects (0.77+) use Swift by default. For existing projects:

```bash
# Follow upgrade helper
# https://react-native-community.github.io/upgrade-helper/
# Select: 0.76 → 0.77

# CRITICAL: Add this line to AppDelegate.swift
RCTAppDependencyProvider.sharedInstance()
```

---

## Common Patterns

### Pattern 1: Conditional Rendering with New Hooks

```typescript
import { useActionState } from 'react';

function LoginForm() {
  const [state, loginAction, isPending] = useActionState(
    async (prevState, formData) => {
      try {
        const user = await api.login(formData);
        return { success: true, user };
      } catch (error) {
        return { success: false, error: error.message };
      }
    },
    { success: false }
  );

  return (
    <View>
      <form action={loginAction}>
        <TextInput name="email" placeholder="Email" />
        <TextInput name="password" secureTextEntry />
        <Button disabled={isPending}>
          {isPending ? 'Logging in...' : 'Login'}
        </Button>
      </form>
      {!state.success && state.error && (
        <Text style={{ color: 'red' }}>{state.error}</Text>
      )}
    </View>
  );
}
```

**When to use:** Form submission with loading/error states

### Pattern 2: TypeScript Instead of propTypes

```typescript
// Define prop types with TypeScript
type ButtonProps = {
  title: string;
  onPress: () => void;
  disabled?: boolean;
  variant?: 'primary' | 'secondary';
};

function Button({ title, onPress, disabled = false, variant = 'primary' }: ButtonProps) {
  return (
    <Pressable
      onPress={onPress}
      disabled={disabled}
      style={[styles.button, styles[variant]]}
    >
      <Text style={styles.text}>{title}</Text>
    </Pressable>
  );
}
```

**When to use:** Always (propTypes removed in React 19)

### Pattern 3: New CSS for Visual Effects

```typescript
// Glowing button with outline and blend mode
function GlowButton({ title, onPress }) {
  return (
    <Pressable
      onPress={onPress}
      style={{
        backgroundColor: '#3b82f6',
        padding: 16,
        borderRadius: 8,
        // Outline doesn't affect layout
        outlineWidth: 2,
        outlineColor: '#60a5fa',
        outlineOffset: 4,
        // Blend with background
        mixBlendMode: 'screen',
        isolation: 'isolate'
      }}
    >
      <Text style={{ color: 'white', fontWeight: 'bold' }}>
        {title}
      </Text>
    </Pressable>
  );
}
```

**When to use:** Visual effects without affecting layout (New Architecture only)

---

## Using Bundled Resources

### Scripts (scripts/)

**check-rn-version.sh** - Detects React Native version and warns about architecture requirements

**Example Usage:**
```bash
./scripts/check-rn-version.sh
# Output: āœ… React Native 0.82 - New Architecture mandatory
# Output: āš ļø React Native 0.75 - Upgrade to 0.76+ recommended
```

### References (references/)

**react-19-migration.md** - Detailed React 19 breaking changes and migration steps

**new-architecture-errors.md** - Common build errors when enabling New Architecture

**expo-sdk-52-breaking.md** - Expo SDK 52+ specific breaking changes

**When Claude should load these:** When encountering migration errors, build failures, or detailed React 19 questions

### Assets (assets/)

**new-arch-decision-tree.md** - Decision tree for choosing React Native version

**css-features-cheatsheet.md** - Complete examples of new CSS properties

---

## Expo SDK 52+ Specifics

### Breaking Changes

**JSC Removed from Expo Go:**
```json
// This no longer works in Expo Go (SDK 52+):
{
  "jsEngine": "jsc"  // āŒ Ignored, Hermes only
}
```

**Google Maps Removed from Expo Go (SDK 53+):**
```bash
# Must use custom dev client for Google Maps
npx expo install expo-dev-client
npx expo run:android
```

**Push Notifications Warning:**
Expo Go shows warnings for push notifications - use custom dev client for production testing.

### New Features (SDK 52)

**expo/fetch (WinterCG-compliant):**
```typescript
import { fetch } from 'expo/fetch';

// Standards-compliant fetch for Workers/Edge runtimes
const response = await fetch('https://api.example.com/data');
```

**React Navigation v7:**
```bash
npm install @react-navigation/native@^7.0.0
```

---

## Official Documentation

- **React Native**: https://reactnative.dev
- **Expo**: https://docs.expo.dev
- **React 19**: https://react.dev/blog/2024/04/25/react-19-upgrade-guide
- **New Architecture**: https://reactnative.dev/docs/new-architecture-intro
- **Upgrade Helper**: https://react-native-community.github.io/upgrade-helper/
- **Context7 Library ID**: /facebook/react-native

---

## Package Versions (Verified 2025-11-22)

```json
{
  "dependencies": {
    "react": "^19.1.0",
    "react-native": "^0.82.0",
    "expo": "~52.0.0",
    "@react-navigation/native": "^7.0.0",
    "@reduxjs/toolkit": "^2.0.0",
    "react-i18next": "^15.0.0"
  },
  "devDependencies": {
    "@types/react": "^19.0.0",
    "typescript": "^5.7.0"
  }
}
```

---

## Troubleshooting

### Problem: Build fails with "Fabric component descriptor not found"
**Solution:** Library not compatible with New Architecture. Check library docs for New Architecture support, or use interop layer (0.76-0.81 only).

### Problem: "propTypes is not a function" error
**Solution:** React 19 removed propTypes. Use TypeScript for type checking instead. Run `npx @codemod/react-19 upgrade`.

### Problem: console.log() not showing in Metro terminal
**Solution:** Metro log forwarding removed in 0.77. Use React Native DevTools Console (press 'j') or `npx expo start --client-logs` (temporary workaround).

### Problem: Swift AppDelegate errors during iOS build
**Solution:** Add `RCTAppDependencyProvider.sharedInstance()` to AppDelegate.swift. See Swift migration section.

### Problem: Redux store crashes on startup
**Solution:** Use Redux Toolkit instead of legacy `redux` + `redux-thunk`. Install `@reduxjs/toolkit`.

### Problem: Can't disable New Architecture in 0.82+
**Solution:** New Architecture is mandatory in 0.82+. If you need legacy, stay on 0.81 or earlier (not recommended).

---

## Complete Setup Checklist

Use this checklist to verify your setup:

- [ ] React Native 0.76+ or Expo SDK 52+ installed
- [ ] New Architecture enabled (automatic in 0.82+)
- [ ] Hermes engine enabled (default)
- [ ] React 19 migration complete (no propTypes, no forwardRef)
- [ ] TypeScript configured for type checking
- [ ] React Native DevTools accessible (press 'j')
- [ ] No deep imports (`react-native/Libraries/*`)
- [ ] Redux Toolkit (not legacy redux)
- [ ] react-i18next (not i18n-js)
- [ ] iOS builds successfully (Swift template if new project)
- [ ] Android builds successfully
- [ ] Dev server runs without errors
- [ ] All navigation/state management working

---

**Questions? Issues?**

1. Check `references/new-architecture-errors.md` for build errors
2. Check `references/react-19-migration.md` for React 19 issues
3. Check official docs: https://reactnative.dev/docs/new-architecture-intro
4. Ensure New Architecture is enabled (mandatory in 0.82+)
5. Verify all dependencies support New Architecture

---

**Knowledge Gap Filled:** This skill covers React Native updates from December 2024+ that LLMs won't know about. Without this skill, Claude would suggest deprecated APIs, removed features, and outdated patterns.

Overview

This skill helps you build and migrate Expo apps targeting React Native 0.76+ and Expo SDK 52+. It codifies migration guidance for the mandatory New Architecture (0.82+), React 19 API changes, new CSS support, the Swift iOS template, and DevTools migration. Use it to avoid common errors and speed troubleshooting during upgrades or new project setup.

How this skill works

The skill inspects typical upgrade and build failure modes and provides concrete fixes: verify New Architecture configuration, update or replace incompatible libraries, apply React 19 codemods, and adjust iOS AppDelegate Swift templates. It also maps runtime and build errors to actionable steps (e.g., add RCTAppDependencyProvider, replace propTypes with TypeScript, switch to Hermes). Included commands and quick-start steps get a new Expo app running with RN 0.76+ and SDK 52.

When to use it

  • Creating a new Expo app with RN 0.76+ / Expo SDK 52
  • Migrating an existing app to React Native 0.76–0.82+ or the New Architecture
  • Troubleshooting build errors like Fabric/TurboModule or Swift AppDelegate issues
  • Replacing propTypes/forwardRef usages after upgrading to React 19
  • Adapting to DevTools and Hermes-only runtime changes

Best practices

  • Create a fresh Expo app or upgrade incrementally: move to 0.76–0.81 first, then to 0.82+
  • Run the React 19 codemod to remove propTypes and update forwardRef patterns
  • Use TypeScript for prop validation instead of propTypes for future-proofing
  • Confirm newArchEnabled and never attempt to disable New Architecture in 0.82+
  • Use React Native DevTools (press 'j') for console/inspect instead of the old Chrome debugger

Example use cases

  • Quick-start a new Expo project with RN 0.76+ and SDK 52 and validate New Architecture is enabled
  • Migrate a legacy app that used propTypes and forwardRef to React 19 patterns and TypeScript
  • Fix a build failing with "Fabric component descriptor not found" by updating libraries to Fabric-compatible versions
  • Resolve 'TurboModule not registered' by ensuring native modules expose TurboModules or use the interop layer when available
  • Add RCTAppDependencyProvider.sharedInstance() to AppDelegate.swift when migrating from Objective-C to the Swift template

FAQ

What if my build fails with newArchEnabled=false?

Do not set newArchEnabled to false on 0.82+. Upgrade through 0.76–0.81 first, fix incompatible dependencies, and then move to 0.82+ where legacy is removed.

Chrome debugger no longer works — what replaces it?

Use React Native DevTools (open with 'j' in the Expo CLI or via the Dev Menu). It provides a JS console, breakpoints, and inspection over the Chrome DevTools Protocol.