feat(mobile): upgrade to Expo SDK 57 / React Native 0.86.3 #150
No reviewers
Labels
No labels
dependencies
major
security-pin
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
trails-cool/trails!150
Loading…
Reference in a new issue
No description provided.
Delete branch "upgrade-expo-sdk-57"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Moves
apps/mobilefrom Expo SDK 56 to SDK 57. All 25 version specs are taken from SDK 57's ownbundledNativeModules.jsonrather than chosen by hand.Headline moves:
expo~56.0.12 → ~57.0.22 ·react-native0.85.3 → 0.86.3 ·expo-router~56.2.19 → ~57.0.21 ·react-native-reanimated4.3 → 4.5.1 ·react-native-worklets0.8.3 → 0.10.1, plus everyexpo-*package.Dependency decisions
reactunchanged. SDK 57 pins react to exactly19.2.3, which is what the catalog already carries after #147. No change needed.@types/reactpinned to~19.2.4, mobile-only. Unlikereact, it is not inpnpm-workspace.yaml'soverridesblock, so a per-app pin actually takes effect. journal, planner and@trails-cool/uikeep the catalog's 19.3.0; mobile does not depend on@trails-cool/ui, so the split does not produce clashing React types. This clears the lastexpo install --checkfinding.@sentry/react-nativedeliberately left on 8.x. SDK 57's bundled list names~7.11.0— a major downgrade. The package is already inexpo.install.excludefor exactly this reason. Don't letexpo install --fix"correct" it.Unmanaged native deps, checked against RN 0.86 before starting
@maplibre/maplibre-react-nativereact-native >=0.80.0@sentry/react-native8.26.0react-native >=0.65.0@gorhom/bottom-sheetreanimated >=4.0.0-(57 ships 4.5.1)expo-router/unstable-native-tabswas the main risk, being an unstable API across a major. It still ships in 57, andNativeTabs.Triggerstill exposes.Label/.Icon/.Badgewith the samesf/md{default,selected}shape, soapp/(tabs)/_layout.tsxis unchanged.android/andios/are gitignored (CNG), so there is no hand-edited native code to reconcile.Verification
expo install --checkpnpm typecheck/lint/testexpo prebuild --cleangradle assembleDebugNativeTabslayoutVerified on an Android emulator (Pixel 6 Pro, API 34) after rebasing onto
mainso the map from #148 was present — the SDK upgrade is confirmed against the new map screen, not just against the old placeholder.🤖 Generated with Claude Code
Apps linked against the iOS 27 SDK are killed at launch unless they adopt UIScene (Apple TN3187). Expo's prebuild template still emits an AppDelegate/window lifecycle with no UIApplicationSceneManifest, so a freshly prebuilt app dies before any JS runs: Application failed to launch: UIScene life cycle is required for apps built with this SDK. This is not specific to SDK 57 — SDK 56 fails identically. Expo tracks it in expo/expo#46664 (accepted, unreleased) and the fix is tied to React Native 0.87+, so it lands no earlier than SDK 58. Adds a config plugin that injects UIApplicationSceneManifest into Info.plist and patches the generated AppDelegate.swift with a SceneDelegate. It is taken from narrowstacks/dorkroom#205, itself derived from YesterdaysLemon/expo-ios-scene-lifecycle-plugin. Beyond the minimum manifest it forwards deep links, universal links and quick actions to the Expo app-delegate subscribers, and re-dispatches the scene activation callbacks, because UIKit stops calling the UIApplicationDelegate life-cycle methods that Expo modules still rely on. Deep-link forwarding matters here specifically: OAuth sign-in returns through trailscool://auth/callback. Two adjustments were needed for this repo: - @expo/config-plugins becomes a direct devDependency. pnpm's isolated linker does not hoist it, so a local plugin cannot resolve it (the upstream PR uses bun, where it happens to be hoisted). - eslint gets an override for apps/mobile/plugins. Config plugins run in Node during prebuild and must be CommonJS, which the repo's ESM rules otherwise reject. Every anchor in the AppDelegate patch throws when it stops matching, so a future template change fails prebuild loudly rather than silently producing a non-scene, crashing app. Remove the plugin once Expo ships a scene-based template. Verified on an iOS 27 simulator (iPhone 17 Pro, Xcode 27): prebuild injects the manifest and SceneDelegate, the app builds, launches, loads 2492 modules from Metro and renders — where the same build without the plugin was killed at launch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>28282be3c1ce1a8659f3