Skip to content

refactor(MainNavigator): migrate MainNavigator to native stack#31606

Merged
weitingsun merged 3 commits into
mainfrom
wsun/migrate-main-navigator-to-native-stack
Jun 12, 2026
Merged

refactor(MainNavigator): migrate MainNavigator to native stack#31606
weitingsun merged 3 commits into
mainfrom
wsun/migrate-main-navigator-to-native-stack

Conversation

@weitingsun

@weitingsun weitingsun commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Description

Migrates the root MainNavigator stack from @react-navigation/stack to @react-navigation/native-stack. Nested navigators in this file were already native stack; this aligns the top-level app stack for native transitions and performance.

Navigation option mappings:

  1. cardStyle → contentStyle
  2. JS slideFromRightAnimation / fadeAnimation → slideFromRightNativeOptions / fadeNativeOptions
  3. Transparent overlays → clearNativeStackNavigatorOptions + transparentModalScreenOptions
  4. DEPRECATED_NETWORK_DETAILS → presentation: 'transparentModal'
  5. Routes.CARD.ROOT → fullScreenModalSlideFromBottomNativeOptions (slide_from_bottom with default card presentation for full-screen + safe area)

Tests: MainNavigator.test.tsx updated for native-stack options.

Changelog

CHANGELOG entry:null

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-585

Manual testing steps

Feature: MainNavigator native stack migration
  
Scenario: Core wallet navigation still works
    Given the app is unlocked on the home tabs
    When the user opens Settings, an asset, Send, and returns home
    Then each screen pushes and pops without navigation errors
    And headers and back gestures behave as expected

Scenario: Modal and overlay flows
    Given the app is on the home screen
    When the user opens Bridge modals, Earn modals, Ramp headless entry, or Stake modals
    Then overlays appear without a dimmed full-screen push animation
    And dismissing returns to the previous screen cleanly
 
Scenario: Card flow is full screen with correct safe area
    Given the user can open MetaMask Card
    When Card is presented from wallet / money entry points
    Then the screen is full height (not an iOS sheet below the notch)
    And the header and top content are not clipped by the status bar
 
Scenario: Perps and feature-flagged stacks
    Given Perps (and other enabled feature stacks) are available
    When the user opens Perps, Predict, or Market Insights from normal entry points
    Then nested stacks load and back navigation works
 
Scenario: Developer Options route preview (temporary)
    Given Developer Options is enabled
    When the user opens Developer Options → Main Navigator sections
    Then each listed route navigates without crashing
    And screens that need mocks or wallet state show disabled hints where expected

Screenshots/Recordings

Before

iOS Before:
https://github.com/user-attachments/assets/55f06300-848b-4e2e-9fe5-4238ce8a4156

After

iOS after part 1:
https://github.com/user-attachments/assets/85c693ed-0011-4f6d-bcb2-73ca2aaf80ff

iOS after part 2:
https://github.com/user-attachments/assets/796b5ed9-ed0f-4756-8528-f8b2de30d7ee

Android after part 1:
https://github.com/user-attachments/assets/02953307-87f7-403b-9f32-de88c6d52657

Android after part 2:
https://github.com/user-attachments/assets/cceeda19-c4ad-4bd8-9d58-b466903ba585

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Touches every root-level navigation push/modal in the app; behavior should match prior flows but regressions in transitions, gestures, or full-screen Card safe area are possible without broad manual QA.

Overview
Migrates the app’s root MainNavigator from @react-navigation/stack to @react-navigation/native-stack, so the top-level stack matches the nested navigators that were already on native stack.

The JS Stack navigator, TransitionPresets, and local slideFromRightAnimation / fadeAnimation interpolators are removed. Root screens use shared native presets: cardStylecontentStyle, push animations via slideFromRightNativeOptions / fadeNativeOptions, and overlay routes via clearNativeStackNavigatorOptions + transparentModalScreenOptions (including DEPRECATED_NETWORK_DETAILS as transparentModal). MetaMask Card uses new fullScreenModalSlideFromBottomNativeOptions (slide_from_bottom) instead of ModalSlideFromBottomIOS.

MainNavigator.test.tsx now asserts native-stack animation: 'slide_from_right' instead of JS-stack animationEnabled / cardStyleInterpolator.

Reviewed by Cursor Bugbot for commit be1dc1a. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

…tack

Drop temporary Developer Options route preview used for migration QA and
align MainNavigator naming with native stack navigators throughout the file.

Co-authored-by: Cursor <cursoragent@cursor.com>
@weitingsun weitingsun self-assigned this Jun 12, 2026
@github-actions github-actions Bot added size-M and removed size-XL labels Jun 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeAccounts, SmokeConfirmations, SmokeIdentity, SmokeNetworkAbstractions, SmokeNetworkExpansion, SmokeSwap, SmokeStake, SmokeWalletPlatform, SmokeMoney, SmokePerps, SmokeMultiChainAPI, SmokePredictions, SmokeSeedlessOnboarding, SmokeBrowser, SmokeSnaps
  • Selected Performance tags: @PerformanceLaunch, @PerformanceLogin, @PerformanceOnboarding, @PerformanceSwaps, @PerformanceAssetLoading, @PerformanceAccountList, @PerformancePredict, @PerformancePreps
  • Risk Level: high
  • AI Confidence: 92%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR migrates the root MainNavigator from createStackNavigator (JS-based) to createNativeStackNavigator (native). This is a fundamental architectural change to the app's navigation system that affects EVERY screen in the application.

Key impacts:

  1. Root navigator change: The outermost navigator wrapping ALL screens (Home, Settings, Send, Browser, Swap, Stake, Earn, Perps, Predict, Ramps, Card, Confirmations, etc.) has been migrated from JS stack to native stack.
  2. Animation/transition changes: All screen transitions now use native stack options (slide_from_right, fade, slide_from_bottom) instead of JS-based cardStyleInterpolator functions.
  3. Modal presentation changes: Several screens using presentation: 'modal' with JS stack options are now using presentation: 'transparentModal' with native stack equivalents.
  4. contentStyle vs cardStyle: Background color styling changed from cardStyle to contentStyle.
  5. SetPasswordFlow header: The header configuration changed from direct props to options object.

Since the root navigator is the backbone of ALL navigation in the app, any regression in navigation behavior (gesture handling, transitions, modal presentations, back navigation, deep links) would affect every feature area. All E2E test suites navigate through this root navigator to reach their respective screens, making this a cross-cutting change that warrants running all test tags.

Performance Test Selection:
The migration from JS-based createStackNavigator to createNativeStackNavigator at the root level could have significant performance implications. Native stack navigators are generally more performant (they use native animations instead of JS-driven ones), but the change could affect: (1) App launch time and time-to-interactive (@PerformanceLaunch), (2) Login/unlock flow which navigates through the root stack (@PerformanceLogin), (3) Onboarding flow using SetPasswordFlow which had its header config changed (@PerformanceOnboarding), (4) Swap flows that navigate through the root stack to reach swap screens (@PerformanceSwaps), (5) Asset loading which involves navigation to asset detail screens (@PerformanceAssetLoading), (6) Account list which may be affected by navigation context changes (@PerformanceAccountList), (7) Predict market flows navigating through the root stack (@PerformancePredict), (8) Perps flows navigating through the root stack (@PerformancePreps). All performance scenarios involve navigation through the root MainNavigator, so all performance tags are relevant.

View GitHub Actions results

@weitingsun weitingsun marked this pull request as ready for review June 12, 2026 01:14
@github-actions github-actions Bot added the risk:high AI analysis: high risk label Jun 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚡ Performance Test Results

ℹ️ Performance test results are currently non-blocking and will not block this PR.

2 tests failed · 19 tests · 1 device

📱 Devices tested (1)

Android: Google Pixel 8 Pro (v14.0)

❌ Failed Tests (2)

@metamask-onboarding-team

Test Platform Device Reason Recording
Onboarding Import SRP with +50 accounts, SRP 3 Android Google Pixel 8 Pro (v14.0) Quality gates exceeded 📹 Watch

@mm-perps-engineering-team

Test Platform Device Reason Recording
Perps open position and close it Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch
✅ Passed Tests (17)
Test Platform Device Duration Team Recording
Aggregated Balance Loading Time, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 8.64s @assets-dev-team 📹 Watch
Cross-chain swap flow - ETH to SOL - 50+ accounts, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 4.71s @swap-bridge-dev-team 📹 Watch
Asset View, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 4.11s @assets-dev-team 📹 Watch
Swap flow - ETH to LINK, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 3.08s @swap-bridge-dev-team 📹 Watch
Cold Start: Measure ColdStart To Login Screen Android Google Pixel 8 Pro (v14.0) 4.15s @metamask-mobile-platform 📹 Watch
Measure Warm Start: Login To Wallet Screen Android Google Pixel 8 Pro (v14.0) 1.28s @metamask-mobile-platform 📹 Watch
Measure Warm Start: Warm Start to Login Screen Android Google Pixel 8 Pro (v14.0) 0.99s @metamask-mobile-platform 📹 Watch
Perps add funds Android Google Pixel 8 Pro (v14.0) 10.01s @mm-perps-engineering-team 📹 Watch
Predict Available Balance - Complete Flow Performance Android Google Pixel 8 Pro (v14.0) 1.14s @team-predict 📹 Watch
Predict Deposit - Complete Flow Performance Android Google Pixel 8 Pro (v14.0) 12.58s @team-predict 📹 Watch
Predict Market Details - Complete Flow Performance Android Google Pixel 8 Pro (v14.0) 4.84s @team-predict 📹 Watch
Connect to Uniswap dapp, edit accounts, choose another account, and skip Solana popup Android Google Pixel 8 Pro (v14.0) 18.38s @metamask-mobile-platform 📹 Watch
Cold Start after importing a wallet Android Google Pixel 8 Pro (v14.0) 0.89s @metamask-mobile-platform 📹 Watch
Measure Cold Start To Onboarding Screen Android Google Pixel 8 Pro (v14.0) 2.40s @metamask-mobile-platform 📹 Watch
Account creation after fresh install Android Google Pixel 8 Pro (v14.0) 3.87s @metamask-onboarding-team 📹 Watch
Seedless Onboarding: Apple Login New User Android Google Pixel 8 Pro (v14.0) 11.99s @metamask-onboarding-team 📹 Watch
Seedless Onboarding: Google Login New User Android Google Pixel 8 Pro (v14.0) 11.13s @metamask-onboarding-team 📹 Watch

Branch: wsun/migrate-main-navigator-to-native-stack · Build: Normal · Commit: 0911c8d · View full run

@weitingsun weitingsun added this pull request to the merge queue Jun 12, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 12, 2026
@weitingsun weitingsun added this pull request to the merge queue Jun 12, 2026
Merged via the queue into main with commit 32e049d Jun 12, 2026
201 checks passed
@weitingsun weitingsun deleted the wsun/migrate-main-navigator-to-native-stack branch June 12, 2026 17:15
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

risk:high AI analysis: high risk size-M team-mobile-platform Mobile Platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants