Every Expo SDK upgrade comes with a migration guide. Every Expo SDK upgrade also comes with three things the migration guide doesn't mention. Here's what we've hit across the 52 → 53 → 54 → 55 → 56 cycle.
The category 1 landmine: peer-dep drift
Expo SDK pins React Native to a specific version. React Native pins React. React pins TypeScript's JSX transform. When you bump Expo, the entire pin tree shifts — and whatever non-Expo packages you've added (react-query, zod, react-hook-form) suddenly need minor bumps to stay compatible.
The giveaway: your app builds, runs once, then crashes on a second reload with an opaque useSyncExternalStore error.
The fix, in order:
npx expo install --fix
pnpm up
# Then delete node_modules + lockfile and start over if it still complainsCategory 2: behavior changes that aren't in the changelog
These hurt more because your build is green:
- SDK 54:
Keyboardevents shifted ~16ms earlier. If you were timing autoscroll to the keyboard show event, it now scrolls before the keyboard is actually visible. - SDK 55: The safe-area insets became reactive to orientation changes. Any layout that used
useSafeAreaInsets().topinStyleSheet.create(computed once) silently broke on rotation. - SDK 56:
expo-router'suseLocalSearchParamsstarted returningundefinedduring transitions instead of the previous-route's params. Fine unless you were relying on that.
None of these are in release notes as "breaking." They're "corrected behavior" that is nonetheless a breaking change for your app.
Category 3: native module incompatibilities
Third-party native modules — react-native-mmkv, react-native-reanimated, custom config plugins — lag Expo by a few days to a few weeks. The pattern:
- You bump Expo on a Friday.
expo prebuildsucceeds.- The build fails in Xcode with a CocoaPods deprecation warning that reads like a fatal error.
- You discover the module's
mainbranch already fixed it but the npm release hasn't shipped.
The defensive move: pin any native module that you depend on to a known-good version, and expo install with --fix after pinning.
How to test an upgrade before you ship it
Never merge an SDK upgrade from the same PR that changed anything else. The upgrade itself is the change.
# [!code ++] Clean branch, one responsibility
git checkout -b upgrade/expo-57
npx expo install expo@latest
npx expo install --fix
pnpm ios # run the golden-path user flows
pnpm androidIf your app has a setup checklist (ours does), run the full thing after upgrade. You'll catch 80% of the category-2 stuff inside 20 minutes.
The one thing that will save you an afternoon
Keep a running upgrade log per SDK bump: what broke, what you fixed, what you couldn't figure out. Past-you is your best resource. After three upgrades you'll have a personal field guide that's better than any release notes.
If you want to skip the first round of pain, our starter kit ships with pinned-and-tested versions for every SDK we support, and Evergreen subscribers get the patch notes and diffs the moment a new SDK drops.
Read more
React Native + Supabase: The Stack We'd Pick to Ship an App in 2026
A opinionated look at why React Native with Expo and Supabase is the fastest way to a production mobile app in 2026 — and the three places it bites you.
Apple Sign-In, Google Sign-In, and Magic Links: Which Auth Flow Ships Fastest?
A practical comparison of the three most common mobile auth flows — how long each actually takes to wire up, what breaks on submission, and when to use which.
RevenueCat vs Stripe for Mobile In-App Purchases: When to Use Which
A decision framework for mobile payments: when RevenueCat's abstraction pays for itself, when Stripe's native sheet is enough, and when you need both.