React Native Roadmap 2026-W22
Week of May 25–May 31, 2026
Items This Week
| # | Title | Label | Link |
|---|---|---|---|
| 1 | Expo UI is now stable: SwiftUI and Jetpack Compose from a single import | 🟧 EXPO | Read |
| 2 | Expo Router v56: Decoupling from React Navigation | 🟧 EXPO | Read |
| 3 | Worklet integration in Expo UI: synchronously controlling SwiftUI and Compose state | 🟧 EXPO | Read |
| 4 | React Native Gesture Handler 3.0 | 🟦 RN | Read |
| 5 | React Native Reanimated 4.4 – CSS animation engine on iOS | 🟦 RN | Read |
5-Day Action Plan
Â
🟧 Chunk 1 — Integrate Expo UI Stable Components (SwiftUI + Compose)
Goal: Replace custom-built UI elements with real SwiftUI (iOS) and Jetpack Compose (Android) components via the now-stable expo-ui library, giving end users a polished native look and feel with zero Swift/Kotlin code.
Scope:
- Upgrade
expoto SDK 56 and addexpo-uito dependencies - Identify one screen with a bottom sheet, picker, or segmented control that can be replaced
- Implement the Expo UI native component with proper platform-specific props
- Validate rendering on both iOS and Android simulators
Out of scope: Full app-wide UI migration; writing custom native modules; iOS/Android-only exclusive features.
Dependencies: None — this is the entry-point chunk for SDK 56 adoption.
Acceptance criteria:
- The targeted component renders as genuine SwiftUI on iOS and Jetpack Compose on Android (confirmed via Xcode View Hierarchy / Android Layout Inspector)
- No JS-thread animation jank observed
- A non-technical stakeholder confirms the component looks and behaves natively
- No regressions on existing screens
Estimated effort: M
Â
**Copy/paste this prompt:**
Implement the following React Native chunk for your mobile app:
Goal: Integrate the stable expo-ui library (Expo SDK 56) to replace a custom UI element with a native SwiftUI (iOS) / Jetpack Compose (Android) component.
Files to create or modify:
package.json— bumpexpoto SDK 56, addexpo-uiapp/(tabs)/settings.tsx(or equivalent screen) — replace custom picker/bottom sheet with Expo UI componentapp.json/app.config.ts— ensure SDK 56 config
Step-by-step instructions:
- Run
npx expo install expo-uiand ensureexpois on SDK 56 - Import the target component from
expo-ui(e.g.,BottomSheet,Picker, orSegmentedControl) - Replace the existing custom component on one screen with the Expo UI equivalent
- Add platform-specific props where needed (iOS-specific SwiftUI styling, Android Compose theming)
- Run
npx expo run:iosandnpx expo run:androidto validate
Acceptance criteria checklist:
- Component renders natively (SwiftUI on iOS, Compose on Android) — verified via native inspector
- No JS-thread animation jank (check with React DevTools Profiler)
- All existing navigation and business logic on the screen still works
- No TypeScript errors or console warnings
🟧 Chunk 2 — Migrate to Expo Router v56 (Decoupled Navigation)
Goal: Upgrade Expo Router to v56 to unlock its fork from React Navigation, streaming SSR, new Android toolbar, and Native Tabs improvements — reducing navigation bundle size and improving cross-platform consistency.
Scope:
- Upgrade
expo-routerto v56 inpackage.json - Apply all breaking-change migration steps from the official upgrade guide
- Test all existing navigation flows: tab navigation, stack push/pop, deep links, modals
- Validate the new Android toolbar appearance on a physical device or emulator
Out of scope: Adding new routes or screens; redesigning navigation UX; implementing streaming SSR features.
Dependencies: Chunk 1 (Expo SDK 56 upgrade completed).
Acceptance criteria:
- All existing routes navigate correctly without crashes
- Deep links resolve to the correct screen
- Android toolbar renders with correct title and back arrow
- No
console.errororconsole.warnoutput related to navigation
Estimated effort: M
Â
**Copy/paste this prompt:**
Implement the following React Native chunk for your mobile app:
Goal: Upgrade Expo Router to v56, which decouples from React Navigation, and ensure all navigation flows work correctly.
Files to create or modify:
package.json— upgradeexpo-routerto^56.0.0app/_layout.tsx— apply any breaking API changes (new Stack/Tabs props, removed APIs)app/(tabs)/_layout.tsx— update Native Tabs configuration if changed- Any file using
useRouter,useLocalSearchParams,Link,Redirect— check for deprecated APIs
Step-by-step instructions:
- Run
npx expo install expo-router@^56and resolve peer deps - Read the Expo Router v56 migration guide for breaking changes
- Update
_layout.tsxfiles to use new Stack/Tabs APIs if changed - Run
npx expo run:iosand test: tab switch, stack push, modal open, deep link - Run
npx expo run:androidand verify Android toolbar (title + back navigation) - Test deep linking with
npx uri-scheme open myapp://your-route --ios
Acceptance criteria checklist:
- All tab screens render without blank screen
- Stack navigation push/pop works correctly
- Modal opens and closes without crash
- Deep link resolves to correct screen on iOS and Android
- No navigation-related errors in Metro logs
🟦 Chunk 3 — Upgrade to React Native Gesture Handler 3.0
Goal: Adopt Gesture Handler 3.0, fully rebuilt for the New Architecture with a hook-based API and a new Touchable component, ensuring all touch interactions remain reliable and forward-compatible on both platforms.
Scope:
- Upgrade
react-native-gesture-handlerto 3.0 inpackage.json - Migrate existing gesture compositions to the new hook-based API (
useAnimatedReaction,useGesture, etc.) - Replace deprecated
TouchableOpacity/TouchableNativeFeedbackusages with the newTouchablecomponent where applicable - Run a manual gesture QA pass on iOS and Android
Out of scope: Adding new gestures; building new interactive animations; pan/pinch/rotate complex combos.
Dependencies: New Architecture must be enabled (newArchEnabled: true in app.json); React Native 0.85+.
Acceptance criteria:
- All existing swipe, tap, and long-press interactions work on both platforms
- No deprecated API warnings in the Metro console
- A QA tester confirms gestures feel responsive and correct
Estimated effort: S
Â
**Copy/paste this prompt:**
Implement the following React Native chunk for your mobile app:
Goal: Upgrade react-native-gesture-handler to v3.0, migrate to its hook-based API, and validate all gesture interactions.
Files to create or modify:
package.json— upgradereact-native-gesture-handlerto^3.0.0App.tsxorapp/_layout.tsx— ensureGestureHandlerRootViewwraps the root- Any component using
PanGestureHandler,TapGestureHandler,LongPressGestureHandler— migrate to hook-based API - Any component using
TouchableOpacityfrom gesture-handler — replace with newTouchable
Step-by-step instructions:
- Run
npx expo install react-native-gesture-handler@^3.0.0 - Wrap your app root in
<GestureHandlerRootView style={{ flex: 1 }}>if not already done - For each gesture handler component, migrate to the v3 hook-based API:
- Replace
<PanGestureHandler onGestureEvent={...}>withconst pan = Gesture.Pan().onUpdate(...)+<GestureDetector gesture={pan}>
- Replace
- Replace deprecated
Touchable*from gesture-handler with the newTouchablecomponent - Test on iOS simulator: swipe list items, tap buttons, long-press menu triggers
- Test on Android emulator: same gestures; confirm no ANR or jank
Acceptance criteria checklist:
- No
DeprecationWarningin Metro logs related to gesture-handler - Swipe-to-dismiss / swipe list actions work correctly
- Tap and long-press handlers fire at correct timing
- GestureHandlerRootView wraps the entire app
- New Architecture flag is enabled and confirmed working
🟦 Chunk 4 — Enable Reanimated 4.4 CSS Animations via Core Animation on iOS
Goal: Upgrade to Reanimated 4.4 and enable its new iOS CSS animation engine, which runs animations through Core Animation instead of a JS-driven loop — delivering smoother 60/120fps animations without JS-thread involvement.
Scope:
- Upgrade
react-native-reanimatedto 4.4 inpackage.json - Enable the new CSS animation engine (opt-in flag if required)
- Identify 2–3 existing animations that benefit most (transitions, fade-ins, slide-ins)
- Measure FPS before and after with Flipper or the React Native DevTools Profiler
Out of scope: Migrating all animations at once; Android-specific animation engine changes; building new animations.
Dependencies: Chunk 3 (Gesture Handler 3.0 for a cohesive animation/gesture stack); Expo SDK 56 / RN 0.85+.
Acceptance criteria:
- Target animations run at ≥60 FPS on a physical iOS device (confirmed with Xcode Instruments or Flipper)
- No visual regression on Android
- A before/after FPS comparison screenshot is shared with the team
Estimated effort: S
Â
**Copy/paste this prompt:**
Implement the following React Native chunk for your mobile app:
Goal: Upgrade react-native-reanimated to 4.4 and enable the new iOS CSS animation engine that offloads animations to Core Animation.
Files to create or modify:
package.json— upgradereact-native-reanimatedto^4.4.0babel.config.js— confirmreact-native-reanimated/pluginis listedmetro.config.js— no change expected, but verify- Any component using
useAnimatedStyle,withTiming,withSpring— check for deprecated API usage - One feature screen with a visible animation (e.g., modal slide, tab transition, card fade)
Step-by-step instructions:
- Run
npx expo install react-native-reanimated@^4.4.0 - Check the Reanimated 4.4 changelog for opt-in flags for the iOS CSS animation engine
- Enable the CSS animation engine in your config if it is opt-in (e.g., in
app.jsonor via a plugin) - Locate 2-3 existing
withTimingorwithSpringanimations in your app - Run the app on a physical iOS device
- Open Xcode Instruments → Core Animation → record while triggering the animations
- Compare FPS with and without the new engine enabled
Acceptance criteria checklist:
-
react-native-reanimatedupgraded to 4.4 without peer dependency conflicts - Animations run at ≥60 FPS on physical iOS device (Instruments screenshot captured)
- No visual regressions on Android (test same animations on emulator)
- No new console warnings or errors related to Reanimated
- Before/after FPS comparison documented
🟧 Chunk 5 — Implement Worklet-Driven Expo UI for Synchronous Native State
Goal: Use Expo UI's new Worklet integration to synchronously drive SwiftUI/Compose component state from JS animations — eliminating bridge latency and enabling butter-smooth interactive controls (e.g., a native slider or segmented control driven by Reanimated).
Scope:
- Identify one interactive Expo UI native component (e.g.,
BottomSheetposition, customSlider, orSwitch) - Integrate a Reanimated shared value (
useSharedValue) to drive its native state synchronously via the worklet bridge - Test interaction responsiveness on both iOS and Android
- Document the worklet + Expo UI pattern in a code comment for future reference
Out of scope: Complex multi-gesture animations; full Reanimated migration; building new Expo UI components from scratch.
Dependencies: Chunk 1 (Expo UI stable integrated); Chunk 4 (Reanimated 4.4 with CSS engine enabled).
Acceptance criteria:
- User input on the native component responds without perceptible JS-thread latency (< 16ms response time)
- The shared value updates synchronously — confirmed by logging worklet execution context
- Works correctly on both iOS (SwiftUI) and Android (Compose)
- A non-technical stakeholder confirms the interaction feels "native and instant"
Estimated effort: M
Â
**Copy/paste this prompt:**
Implement the following React Native chunk for your mobile app:
Goal: Connect a Reanimated worklet to an Expo UI native component (SwiftUI/Compose) so its state is driven synchronously without JS-thread round-trips.
Files to create or modify:
components/NativeSlider.tsx(new file) — worklet-driven Expo UI componentapp/(tabs)/index.tsx(or equivalent) — integrate the new NativeSlider componentpackage.json— confirmexpo-uiandreact-native-reanimatedare at correct versions (SDK 56, Reanimated 4.4)
Step-by-step instructions:
- Create
components/NativeSlider.tsx:import { useSharedValue, runOnUI } from 'react-native-reanimated'; import { Slider } from 'expo-ui'; // adjust import per expo-ui API export function NativeSlider() { const progress = useSharedValue(0); const onValueChange = (value: number) => { runOnUI(() => { 'worklet'; progress.value = value; })(); }; return <Slider value={progress} onValueChange={onValueChange} />; } - Review the Expo UI Worklets blog post for the exact API
- Adjust the component to use the correct Expo UI worklet binding API as documented
- Integrate
<NativeSlider />into a screen in your app - Test on iOS: drag slider rapidly — confirm no stutter or delay
- Test on Android: same test — confirm Compose updates synchronously
- Add a code comment explaining the worklet pattern for future contributors
Acceptance criteria checklist:
- Slider/control responds to input without visible lag (test by dragging rapidly)
- Worklet executes on the UI thread (log
_WORKLETcontext inside the worklet) - Component renders correctly on both iOS (SwiftUI) and Android (Compose)
- No JS-thread warnings or bridge overflow errors
- Code comment documents the pattern for future use