Skip to content

About

Master React Native & Expo: New Architecture (TurboModules & Fabric), Expo Router, reanimated 3, native primitives, gestures, and production iOS/Android deployments

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

Learn React Native 📱

License: MIT React Native Version Expo SDK Engine Architecture Production Ready

An exhaustive, production-grade masterclass from absolute zero to staff-level React Native and Expo mobile architecture.
Master the New Architecture (Fabric & TurboModules), Bridgeless execution, Hermes ahead-of-time bytecode compilation, Expo Router file-system navigation, Reanimated 3 UI-thread worklets, MMKV storage, and production iOS/Android deployments.

Getting Started • Core Primitives • Expo Router • Gestures & Animations • Device Hardware • Performance & EAS • Staff Handbook


Buy Me A Coffee

🗺️ 7-Stage Pedagogical Roadmap

flowchart LR
    S1["Stage 1: New Architecture & Hermes"] --> S2["Stage 2: Core Primitives & Yoga Flexbox"]
    S2 --> S3["Stage 3: Expo Router Navigation"]
    S3 --> S4["Stage 4: Gestures & Reanimated 3"]
    S4 --> S5["Stage 5: Hardware & MMKV Storage"]
    S5 --> S6["Stage 6: Profiling, Offline & EAS"]
    S6 --> S7["Stage 7: Staff Architect Handbook & Cheatsheet"]
Loading
Stage Domain Focus Core Concepts & Production Outcomes
Stage 1 New Architecture & Foundations The death of the asynchronous Bridge, JSI (JavaScript Interface), C++ core, Fabric rendering engine, TurboModules, Hermes AOT compilation.
Stage 2 Core Primitives & Yoga Layout Yoga C++ Flexbox engine, <View>, <Text>, <Image>, <ScrollView>, virtualized lists (<FlatList>, @shopify/flash-list), Safe Area handling.
Stage 3 Expo Router Navigation Next.js-style file-based routing for native iOS/Android, Stack, Tabs, Drawer, modal interceptors, deep linking, auth protected route groups.
Stage 4 Gestures & 60fps Animations React Native Gesture Handler, Reanimated 3 worklets running on the UI thread, pan gestures, layout animations, shared element transitions.
Stage 5 Hardware & High-Speed Storage Camera, Geolocation, Biometrics (FaceID/Fingerprint), High-throughput synchronous storage with react-native-mmkv vs SQLite.
Stage 6 Performance, Offline-First & EAS Hermes trace profiling, JS thread vs UI thread frame drops, WatermelonDB/SQLite offline sync, EAS Build & OTA updates (EAS Update).
Stage 7 Staff Architect Interview Handbook 40+ staff-level scenario Q&As, Bridge vs Bridgeless benchmarks, memory leak isolation, multi-platform monorepos, enterprise cheatsheet.

📋 Table of Contents


1. Stage 1: Foundations & The New Architecture

1.1 Why the Old Bridge Failed: The JSON Serialization Bottleneck

In the legacy React Native architecture, JavaScript and Native platforms communicated across an asynchronous Bridge:

graph TD
    subgraph OldBridge ["Legacy Architecture (The Asynchronous Bridge)"]
        JS1["JavaScript Thread"] -->|1. Serialize to JSON String| Bridge["Async Serialized JSON Bridge"]
        Bridge -->|2. Queue & Send over Socket| Native1["Native Thread (iOS / Android)"]
        Native1 -->|3. Deserialize JSON & Update UI| FrameDrop["Frame Drops on Heavy Scrolling!"]
    end

    subgraph NewArch ["The New Architecture (JSI / Bridgeless Mode)"]
        JS2["JavaScript (Hermes Engine)"] -->|Direct C++ Memory Pointer Invocation (JSI)| HostObjects["Native Host Objects (C++)"]
        HostObjects -->|Synchronous, Zero-Copy Execution| Native2["Fabric Renderer & TurboModules"]
    end
Loading

The old bridge suffered from 3 fatal flaws:

  1. Asynchronous Serialization Overhead: Every string, layout coordinate, and touch event had to be converted to JSON strings and parsed on both ends.
  2. No Synchronous Execution: JavaScript could not synchronously inspect native measurements or trigger native operations without a roundtrip delay.
  3. Queue Congestion: Fast scrolling resulted in white blank boxes because layout updates queued behind heavy JavaScript computations.

1.2 The New Architecture: JSI, Fabric, and TurboModules

  • JSI (JavaScript Interface): A lightweight, general-purpose C++ API that allows JavaScript code to directly hold references to C++ Host Objects and call methods synchronously without JSON serialization.
  • Fabric: The modern rendering engine built entirely in C++. It creates an immutable C++ shadow tree and coordinates layout directly with Yoga on background threads.
  • TurboModules: Native modules that load lazily on demand. In the legacy architecture, all native modules were instantiated on app boot, dragging down cold startup performance.

1.3 Hermes: Bytecode Precompilation & Instant App Start

Hermes is an open-source JavaScript engine developed by Meta, specifically optimized for mobile applications:

  • AOT (Ahead-of-Time) Compilation: Instead of parsing JavaScript source code at runtime, Hermes compiles JavaScript into bytecode (.hbc) at build time.
  • Instant Cold Starts: The mobile OS loads precompiled bytecode directly into memory via memory-mapped files (mmap), reducing Time-to-Interactive (TTI) by up to 50%.

2. Stage 2: Core Components & Yoga Layout Engine

2.1 The Yoga C++ Flexbox Engine & Platform Differences

Unlike the web where flex-direction defaults to row, React Native uses the Yoga Flexbox engine, where:

  • flexDirection defaults to 'column'.
  • Dimensions are density-independent pixels (dp on Android, points on iOS), never percentages unless specified as strings ('100%').
import React from 'react';
import { View, Text, StyleSheet, Pressable } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

export function DashboardHeader() {
  return (
    <SafeAreaView edges={['top']} style={styles.safeContainer}>
      <View style={styles.headerRow}>
        <View>
          <Text style={styles.greetingText}>Welcome back,</Text>
          <Text style={styles.userNameText}>Alex Morgan</Text>
        </View>
        <Pressable
          style={({ pressed }) => [styles.avatarButton, pressed && styles.avatarPressed]}
          onPress={() => console.log('Profile opened')}
        >
          <Text style={styles.avatarInitials}>AM</Text>
        </Pressable>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  safeContainer: {
    backgroundColor: '#0F172A',
  },
  headerRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: 20,
    paddingVertical: 16,
  },
  greetingText: {
    fontSize: 14,
    color: '#94A3B8',
  },
  userNameText: {
    fontSize: 22,
    fontWeight: '700',
    color: '#F8FAFC',
  },
  avatarButton: {
    width: 44,
    height: 44,
    borderRadius: 22,
    backgroundColor: '#3B82F6',
    justifyContent: 'center',
    alignItems: 'center',
  },
  avatarPressed: {
    opacity: 0.8,
    transform: [{ scale: 0.96 }],
  },
  avatarInitials: {
    color: '#FFFFFF',
    fontWeight: '600',
    fontSize: 16,
  },
});

2.2 High-Performance List Virtualization with FlashList

For lists with hundreds or thousands of items, standard <ScrollView> causes out-of-memory crashes because it renders all items simultaneously. Use @shopify/flash-list, which recycles views instead of unmounting them:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { FlashList } from '@shopify/flash-list';

interface Transaction {
  id: string;
  merchant: string;
  amount: number;
}

export function TransactionHistory({ transactions }: { transactions: Transaction[] }) {
  return (
    <View style={styles.container}>
      <FlashList
        data={transactions}
        estimatedItemSize={72}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => (
          <View style={styles.row}>
            <Text style={styles.merchant}>{item.merchant}</Text>
            <Text style={styles.amount}>${item.amount.toFixed(2)}</Text>
          </View>
        )}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#0F172A' },
  row: {
    height: 72,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#1E293B',
  },
  merchant: { color: '#F8FAFC', fontSize: 16, fontWeight: '500' },
  amount: { color: '#10B981', fontSize: 16, fontWeight: '700' },
});

3. Stage 3: File-Based Navigation with Expo Router

3.1 Modern App Layouts with Expo Router

Expo Router leverages directory hierarchy to declare native iOS and Android navigation:

app/
├── _layout.tsx         # Root Provider & Root Stack Navigator
├── (auth)/             # Route group: Unauthenticated stack
│   ├── login.tsx       # /login
│   └── register.tsx    # /register
├── (tabs)/             # Route group: Tab Navigator
│   ├── _layout.tsx     # Tab configuration
│   ├── index.tsx       # Tab 1: Home
│   └── settings.tsx    # Tab 2: Settings
└── modal.tsx           # Presentation modal sheet
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';

export default function TabLayout() {
  return (
    <Tabs
      screenOptions={{
        headerShown: true,
        tabBarStyle: { backgroundColor: '#0F172A', borderTopColor: '#1E293B' },
        tabBarActiveTintColor: '#38BDF8',
        tabBarInactiveTintColor: '#64748B',
      }}
    >
      <Tabs.Screen
        name="index"
        options={{
          title: 'Home',
          tabBarIcon: ({ color, size }) => <Ionicons name="home" color={color} size={size} />,
        }}
      />
      <Tabs.Screen
        name="settings"
        options={{
          title: 'Settings',
          tabBarIcon: ({ color, size }) => <Ionicons name="settings" color={color} size={size} />,
        }}
      />
    </Tabs>
  );
}

4. Stage 4: 60fps Gestures & Reanimated 3 Animations

4.1 Reanimated 3 Worklets Running on the UI Thread

Standard JavaScript animations drop frames if the JavaScript thread is busy parsing JSON or calculating business logic. Reanimated 3 executes animation functions (Worklets) directly on the native UI thread at 60fps / 120fps (ProMotion):

import React from 'react';
import { StyleSheet, View } from 'react-native';
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';

export function DraggableCard() {
  const translateX = useSharedValue(0);
  const translateY = useSharedValue(0);

  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      'worklet'; // Runs on the native UI thread!
      translateX.value = event.translationX;
      translateY.value = event.translationY;
    })
    .onEnd(() => {
      'worklet';
      // Smooth native spring back to initial position
      translateX.value = withSpring(0, { damping: 15 });
      translateY.value = withSpring(0, { damping: 15 });
    });

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: translateX.value },
      { translateY: translateY.value },
    ],
  }));

  return (
    <View style={styles.container}>
      <GestureDetector gesture={panGesture}>
        <Animated.View style={[styles.card, animatedStyle]} />
      </GestureDetector>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  card: { width: 140, height: 140, borderRadius: 20, backgroundColor: '#8B5CF6' },
});

5. Stage 5: Native Device Hardware & High-Speed Storage

5.1 Synchronous Key-Value Storage with MMKV

AsyncStorage is slow and asynchronous. react-native-mmkv connects directly to Tencent's MMKV C++ engine via JSI, reading and writing synchronously with zero serialization overhead:

import { MMKV } from 'react-native-mmkv';

export const storage = new MMKV({
  id: 'enterprise-app-storage',
  encryptionKey: 'SUPER_SECRET_MMKV_ENCRYPTION_KEY',
});

// Synchronous read and write (100x faster than AsyncStorage!)
export function saveUserAuth(token: string, userId: string) {
  storage.set('auth_token', token);
  storage.set('user_id', userId);
}

export function getAuthToken(): string | undefined {
  return storage.getString('auth_token');
}

6. Stage 6: Enterprise Performance, Profiling & EAS

6.1 Cloud Builds & Over-The-Air (OTA) Updates with Expo EAS

Production deployment pipeline using Expo Application Services (EAS):

// eas.json
{
  "cli": {
    "version": ">= 12.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview"
    },
    "production": {
      "channel": "production",
      "autoIncrement": true
    }
  }
}

Deploying instant bugfixes without waiting for Apple App Store or Google Play review:

# Publish instant OTA update to production channel
eas update --channel production --message "Fix critical checkout rounding error"

7. Stage 7: Staff Mobile Architect Interview Handbook & Cheatsheet

7.1 Enterprise Production Cheatsheet

Component / Library Purpose Recommended Modern Tool
JS Engine Bytecode Ahead-of-Time Engine Hermes (Default in RN 0.70+)
Layout Engine Cross-Platform C++ Flexbox Yoga Engine
Virtual Lists Cell recycling virtualization @shopify/flash-list
Key-Value Storage Synchronous JSI storage react-native-mmkv
Animations Native UI thread worklets react-native-reanimated v3
Routing File-system native navigation Expo Router v4
Builds & CI/CD Cloud builds & OTA hotfixes Expo Application Services (EAS)

7.2 Staff & Principal Architect Interview Q&A (40 Scenarios)

Q1: What was the root cause of the "white blank screen" during fast scrolling in legacy React Native, and how does the New Architecture fix it?

Answer: In the legacy architecture, scroll events were emitted from the native platform, serialized into JSON, queued across the asynchronous Bridge, received by JavaScript, calculated by layout, serialized into new JSON instructions, and queued back to the native thread. On fast scrolls, the JavaScript thread could not keep up with the 60/120Hz display refresh rate, leaving the native view queue empty of rendered cells. With the New Architecture (Fabric), layout is performed synchronously on C++ background threads via JSI with direct zero-copy memory access, eliminating frame drops.

Q2: How does JSI (JavaScript Interface) allow C++ native code to be called synchronously from JavaScript?

Answer: JSI is an abstraction layer that exposes the JavaScript engine's internal runtime to C++. It allows C++ classes to be registered as HostObjects directly into the JavaScript global context. When JavaScript accesses a method on a HostObject, the engine directly invokes the underlying C++ function pointer in the same memory space, completely bypassing JSON serialization.

Q3: Why is AsyncStorage deprecated in high-performance enterprise React Native applications?

Answer: AsyncStorage performs asynchronous SQLite or file-system reads across serialized asynchronous boundaries. Reading an auth token or theme requires async callbacks and causes layout flashing on initial app boot. In contrast, react-native-mmkv uses memory-mapped files (mmap) via JSI, enabling synchronous microsecond reads directly on app startup before the initial view paints.

Q4: What is the architectural difference between React Native and Flutter?

Answer: Flutter bundles its own complete rendering engine (Skia or Impeller) and draws every pixel on a blank native canvas, completely bypassing native OS UI widgets (UIKit/Android Views). React Native leverages the native operating system's genuine UI widgets (UIView, android.view.View), resulting in 100% native accessibility, OS-level text selection, genuine platform look-and-feel, and seamless integration with existing native Swift/Kotlin libraries.

(36 additional Staff-level architecture scenarios detailed inside repository documentation...)


🤝 Contributing

Contributions are welcomed! Fork the repository, create a feature branch, and submit a PR conforming to the unified curriculum architecture.

📄 License

Released under the MIT License.

About

Master React Native & Expo: New Architecture (TurboModules & Fabric), Expo Router, reanimated 3, native primitives, gestures, and production iOS/Android deployments

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages