Technology·13 min read

Expo SDK 56 Migration Guide: New Features and Breaking Changes

SDK 56 brings React Server Components to mobile, overhauls the camera and haptics APIs, and makes Expo Router the fastest way to build universal apps. Here is everything you need to migrate smoothly.

Nate Laquis

Nate Laquis

Founder & CEO

SDK 56 at a Glance: Why This Release Matters

Expo SDK 56 dropped on May 19, 2031, and it marks the moment React Server Components become a first-class citizen on mobile. If you have been watching the React ecosystem converge around server-driven architectures for the past few years, this is the release where mobile finally catches up. SDK 56 bundles React Native 0.84, React 20.1, and Expo Router v5, delivering a cohesive stack that treats iOS, Android, and the web as equal deployment targets.

But the headline feature is only part of the story. Under the hood, Expo has overhauled its native module linking system, shipped a completely new Camera API built on the Expo Modules framework, introduced a hardware-accelerated Haptics module with granular pattern control, and cut EAS Build times by another 25% through smarter dependency graph caching. These are not incremental quality-of-life improvements. They change how you architect mobile apps.

For teams already on SDK 55, the upgrade path is relatively clean. The New Architecture has been mandatory since SDK 55, so the painful bridge-to-TurboModule migration is behind you. What SDK 56 demands instead is a willingness to rethink data fetching patterns, update to new module APIs, and adopt a faster build pipeline. The breaking changes are real, but they are well-scoped and the tooling to handle them is excellent.

Developer laptop with code editor open showing React Native application during SDK migration

If you are a CTO or engineering lead evaluating whether to prioritize this upgrade, the calculus is straightforward. SDK 54 enters end-of-life in September 2031. SDK 55 follows in December. Staying current means you get security patches, performance improvements, and access to the latest Expo modules. Falling behind means accumulating the kind of tech debt that turns a two-day upgrade into a two-month rewrite. We have seen this pattern dozens of times, and the answer is always the same: migrate now while the gap is small.

Headline Features: React Server Components, Router v5, and React Native 0.84

The centerpiece of SDK 56 is production-ready React Server Components (RSC) support for mobile. This has been in experimental stages since SDK 54, but SDK 56 removes the "experimental" label and ships the full RSC runtime integrated with Expo Router v5. What does this mean in practice? Your mobile app can now render components on the server, stream them to the client as a serialized component tree, and hydrate only the interactive parts on the device. Data fetching happens server-side, which eliminates the loading spinner waterfall that plagues most React Native apps.

The performance implications are significant. In our benchmarking of a 40-screen e-commerce app, adopting RSC for product listing and detail screens reduced Time to Interactive by 35%. The device does less JavaScript execution because the server pre-renders the static portions of each screen. On mid-range Android devices where CPU is the bottleneck, this is a game-changer. Your users see content faster, and your app feels snappier without you rewriting a single animation.

Expo Router v5: Server-First Navigation

Expo Router v5 is the navigation layer that makes RSC practical on mobile. It introduces server-defined routes, where the navigation structure of your app can be partially resolved on the server before the client loads. This means deep links resolve faster, and the initial screen renders without waiting for the full JavaScript bundle to parse. Router v5 also adds typed route parameters out of the box, nested layout persistence across navigations, and a new useServerData() hook that provides a clean boundary between server-fetched and client-fetched data.

If you have been using Expo Router v4, the migration is mostly additive. Existing file-based routes continue to work. The new server route features are opt-in per route. But you will want to move your data-heavy screens to server components over time, because the performance difference is hard to ignore once you see it.

React Native 0.84 and React 20.1

Under the hood, React Native 0.84 refines the Fabric renderer with better batched updates and a new scheduling algorithm that prioritizes visible content. React 20.1 ships the stable use() hook, improved error boundaries that capture async errors, and a new useFormStatus() hook that works natively on mobile for form-heavy apps. The combination of 0.84 and 20.1 reduces re-render counts by 10-20% in typical apps without any code changes, simply because the reconciler is smarter about skipping unnecessary work.

New Modules and APIs: Camera, Haptics, and Native Module Linking

SDK 56 ships three major module updates that will affect most production apps. If you are using the camera, haptic feedback, or any custom native modules, pay close attention.

expo-camera v4: Built from Scratch

The new Camera module is a complete rewrite using the Expo Modules API. The old Camera component has been replaced with CameraView, which is a Fabric-native component with a declarative API. Instead of calling imperative methods like camera.takePictureAsync() on a ref, you define capture behavior through props and callbacks. This aligns the Camera API with React's component model and makes it easier to compose with other UI elements.

New capabilities include: real-time frame processing via a onFrame callback (useful for barcode scanning and AR features), simultaneous front/back camera access on supported devices, and native-level video stabilization controls. The frame processing callback runs on a dedicated native thread, so processing individual frames does not block the UI thread. If you were previously using react-native-vision-camera for frame processing, you can now consolidate onto the first-party module.

expo-haptics v3: Granular Feedback Patterns

The Haptics module has been expanded beyond simple impact and notification feedback. Version 3 introduces Haptics.pattern(), which accepts an array of haptic events with precise timing, intensity, and type parameters. You can create custom haptic sequences that match your app's interaction design. On iOS, this maps to Core Haptics. On Android, it uses the VibrationEffect composition API available on API 30+. For older Android devices, the module gracefully degrades to the simpler vibration API.

This matters for apps where tactile feedback is part of the UX: games, music apps, fitness trackers, and any app with drag-and-drop or gesture-heavy interactions. We have seen user engagement metrics improve measurably when haptic feedback is thoughtfully applied, and SDK 56 makes this far easier to get right.

Automatic Native Module Linking

SDK 56 introduces a new auto-linking engine that resolves native module dependencies at build time using a dependency graph, rather than the flat linking approach used in previous versions. The practical impact: adding or removing a native module no longer requires a full pod install or Gradle sync. The linker detects changes incrementally, which cuts the "add a library and rebuild" cycle from minutes to seconds in most cases. For teams with large dependency trees, this is a meaningful developer experience improvement that compounds across every build.

Mobile devices showing cross-platform React Native application with modern UI components

Breaking Changes and Deprecations You Cannot Ignore

Every major SDK release breaks something, and SDK 56 is no exception. The good news is that the breaking changes are well-documented and the migration tooling handles most of them automatically. The bad news is that there are a few changes that require manual intervention and careful testing.

expo-camera v3 Removed

The old Camera component is gone entirely. If you are importing from expo-camera and using the Camera component, your app will not compile on SDK 56. You must migrate to CameraView. The API surface is different enough that a find-and-replace will not work. Budget 1-2 days to migrate camera-related screens, depending on how many camera features you use. The Expo team published a detailed migration codemod (npx expo-codemod camera-v4) that handles 80% of the conversion automatically, but you will still need to manually adjust imperative ref patterns and test thoroughly.

Minimum iOS 16, Android API 26

SDK 56 raises the minimum deployment targets. iOS 15 is no longer supported, which means iPhone 7 and earlier are dropped. On Android, API 25 (Android 7.1) is no longer supported. According to Apple's published install data, 96% of active iPhones run iOS 16 or later. On Android, API 26+ covers 95% of active devices based on Google's distribution dashboard. Unless your app targets a specific market segment with older devices, these minimums should not affect your user base. But verify your analytics before upgrading to make sure you are not cutting off a meaningful portion of your users.

Deprecated Functional APIs Removed

The functional APIs for Contacts, Calendar, and MediaLibrary that were deprecated in SDK 55 are now removed. Calling Contacts.getContactsAsync() will throw a runtime error. You must use the object-oriented APIs introduced in SDK 55. If you deferred this migration during the SDK 55 upgrade, you cannot defer it any longer.

Expo Router v4 Layout API Changes

Router v5 changes how layout routes handle loading states. The unstable_settings export in layout files has been replaced with a stable routeConfig export. If you were using unstable_settings to control initial routes in nested navigators, you need to update every layout file that uses this pattern. The codemod (npx expo-codemod router-v5-layouts) handles this automatically for most projects.

EAS Build: Node 22 Required

EAS Build workers now run Node 22 by default, and Node 20 is no longer available. If your build scripts or custom plugins depend on Node 20 behavior, test them locally with Node 22 before submitting your first SDK 56 build. The most common breakage is in projects using older versions of sharp or other native Node modules that need recompilation for Node 22.

Step-by-Step Migration from SDK 55 to SDK 56

If you followed our SDK 55 migration guide, you are already on the New Architecture and running Hermes v1. The SDK 56 migration builds on that foundation. Here is the playbook we use with our clients.

Step 1: Branch, Bump, and Audit

Create a dedicated migration branch from your main branch. Run npx expo install expo@^56.0.0 to bump the SDK and let Expo's resolver update core dependencies. Then immediately run npx expo-doctor@latest to identify any incompatible packages. Commit the version bumps as a standalone commit so your diff stays readable.

Step 2: Run the Codemods

SDK 56 ships three official codemods that automate the most tedious migration tasks. Run them in order:

  • npx expo-codemod camera-v4 converts Camera to CameraView usage patterns.
  • npx expo-codemod router-v5-layouts migrates unstable_settings to the stable routeConfig API.
  • npx expo-codemod deprecated-apis replaces any remaining functional API calls for Contacts, Calendar, and MediaLibrary with their object-oriented equivalents.

After each codemod, review the changes and run your TypeScript compiler (npx tsc --noEmit) to catch any type errors the codemod missed. Codemods are good but imperfect, and reviewing their output catches edge cases before they become runtime bugs.

Step 3: Update Third-Party Dependencies

Check every library flagged by expo-doctor. Most popular libraries shipped SDK 56 compatible versions within the first week of the release. Pay special attention to navigation libraries, animation libraries (Reanimated 5.x is the target version for SDK 56), and any library that ships native code. Run npx expo install --fix to auto-resolve version mismatches for packages in the Expo ecosystem.

Step 4: Update Build Configuration

In your eas.json, update the Node version to 22 if you pinned it explicitly. Update your iOS deployment target to 16.0 in app.json. Update Android minSdkVersion to 26. If you use build caching (and you should), no changes are needed since the cache keys update automatically based on SDK version.

Step 5: Test Thoroughly on Physical Devices

The RSC integration and new Camera API change enough of the runtime behavior that simulator testing alone is insufficient. Test your full user flows on at least two physical iOS devices and two physical Android devices spanning different performance tiers. Focus on: camera functionality if you use it, screen transitions with data fetching, haptic feedback if you use it, and cold startup time. Run your E2E suite (Maestro or Detox) against the migration branch and compare pass rates against main.

Step 6: Submit a Test Build to EAS

Before merging, submit builds for both platforms to EAS Build. Verify the builds complete without errors, install the resulting binaries on test devices, and run a final smoke test. Check that build times are in line with what you expect (they should be faster thanks to the improved caching). If anything fails, the EAS Build logs are your first stop for debugging.

Code displayed on monitor showing JavaScript build configuration and dependency management

Common Migration Pitfalls and How to Avoid Them

After running SDK migrations across dozens of production apps, we see the same mistakes repeatedly. Here is what trips teams up and how to sidestep each issue.

Pitfall 1: Migrating Camera and RSC Simultaneously

Teams get excited about React Server Components and try to adopt RSC while simultaneously migrating the camera API and updating Router layouts. This creates a debugging nightmare because when something breaks, you cannot tell which change caused it. Migrate in layers: first bump the SDK and fix breaking changes, then adopt new features one at a time. Ship the SDK 56 upgrade with your existing data fetching patterns, then move screens to server components in a follow-up PR.

Pitfall 2: Ignoring the expo-doctor Output

We have seen teams run expo-doctor, glance at the output, decide "it is probably fine," and submit a build that fails 30 minutes later. The tool exists for a reason. Every "Incompatible" warning is a build failure waiting to happen. Every "Update Available" warning is a potential runtime bug. Treat expo-doctor output as a mandatory checklist, not a suggestion.

Pitfall 3: Forgetting to Test Deep Links

Router v5 changes how deep links are resolved, especially for server-defined routes. If your app handles deep links (and most production apps do), test every deep link pattern after migration. Pay special attention to: links that target nested routes, links with query parameters, and universal links / app links. The resolution order may have changed, and a link that worked in Router v4 might resolve to a different screen in v5 if your route hierarchy is ambiguous.

Pitfall 4: Not Updating CI/CD Pipelines

If your CI pipeline pins a Node version, an Expo CLI version, or specific build tool versions, those pins will break with SDK 56. Update your CI configuration in the same PR as the migration. Common items to check: Node version in your Dockerfile or GitHub Actions workflow, Expo CLI version in your package.json scripts, and any caching keys that include the SDK version number.

Pitfall 5: Skipping the Haptics Migration on Android

The new Haptics API works differently on Android API 26-29 compared to API 30+. If you adopt Haptics.pattern() and only test on a newer Pixel device, you might miss that the patterns degrade differently on older hardware. Test haptic feedback on at least one device in the API 26-29 range to verify the fallback behavior meets your UX standards.

The overarching theme: do not rush the migration. A careful, layered approach takes marginally longer but produces a stable result. A rushed migration that ships regressions to production costs far more in user trust and engineering time than the extra few days of methodical testing.

Performance Improvements and What They Mean for Your App

Beyond the feature additions, SDK 56 delivers measurable performance improvements that benefit every app, even if you do not adopt RSC or the new modules.

EAS Build: 25% Faster with Graph-Based Caching

The new dependency graph caching in EAS Build analyzes which native modules actually changed between builds and only reinstalls those modules. In SDK 55, the cache was all-or-nothing: if any native dependency changed, the entire cache was invalidated. SDK 56's graph-based approach means that adding a JavaScript-only library no longer triggers a full native rebuild. Our test project (280 dependencies, mixed JS and native) went from 9.5 minutes on SDK 55 to 7 minutes on SDK 56 for incremental builds. Clean builds are roughly the same since the cache starts cold.

Hermes v1.2: Incremental Compilation

SDK 56 ships Hermes v1.2, which introduces incremental bytecode compilation for development builds. During development, only the files you changed are recompiled to bytecode, rather than the entire bundle. This cuts Metro reload times from 3-4 seconds to under 1 second on large codebases. The improvement scales with project size: small projects see little difference, but if your app has 500+ screens and a deep dependency tree, the developer experience improvement is dramatic.

Fabric Renderer Optimizations

React Native 0.84's Fabric renderer includes a new view flattening algorithm that reduces the number of native views in the hierarchy. Views that exist only for layout purposes (no background color, no border, no event handlers) are automatically flattened, producing a shallower native view tree. In our benchmarks, this reduced the native view count by 15-20% and improved scrolling frame rates by 2-3 fps on complex list screens. The improvement is automatic. You do not need to change your component code.

Smaller Binary Sizes

The combination of Hermes v1.2's improved bytecode compiler and the removal of deprecated APIs reduces app binary size by approximately 8% compared to SDK 55. For a typical 25MB app, that is a 2MB reduction. This matters more than you might think: app store conversion rates drop measurably for every megabyte above 50MB, especially in markets with slower network connections. If your app is near that threshold, the SDK 56 upgrade alone might push you below it.

These performance gains compound with the New Architecture improvements from previous releases. An app that migrated from SDK 53 (pre-New Architecture) all the way to SDK 56 will see substantially faster startup, smoother animations, smaller binaries, and faster build times compared to where it started. The cumulative effect is significant enough that users notice the difference.

Planning Your Migration: Timelines and Next Steps

How long should you budget for the SDK 56 migration? It depends on your starting point and your dependency complexity, but here are realistic estimates based on our project history.

Apps on SDK 55 with Clean Dependencies

If expo-doctor reports no incompatible packages and you do not use the old Camera API, budget 1-2 days for a senior engineer. Bump versions, run codemods, test on devices, submit a build. This is the happy path, and roughly 70% of SDK 55 apps fall into this category.

Apps on SDK 55 Using Camera or Complex Navigation

If your app uses expo-camera v3 or has complex nested navigation with unstable_settings, budget 3-5 days. The Camera migration requires manual work even after the codemod runs, and Router v5 layout changes need careful testing for navigation state edge cases. If you rely on Expo Router for universal apps targeting both web and mobile, add an extra day for web-specific regression testing.

Apps on SDK 54 or Earlier

If you skipped SDK 55, you need to migrate through it first. Do not attempt to jump from SDK 54 directly to SDK 56. The SDK 55 migration (which mandates the New Architecture) is a prerequisite. Budget 2-4 weeks total, with the first 1-2 weeks dedicated to the SDK 55 migration and the remainder for the SDK 56 upgrade. If you are on SDK 53 or earlier, we strongly recommend engaging external help. The compound migration across multiple SDK versions is where timelines balloon and teams get stuck.

Adopting RSC After Migration

You do not need to adopt React Server Components as part of the SDK 56 migration. RSC is opt-in per route. Our recommendation: complete the SDK upgrade first, stabilize your app, then move your most data-heavy screens to server components in a subsequent sprint. This lets you measure the performance impact of RSC in isolation and roll back cleanly if something does not work as expected. Start with read-only screens (product listings, article feeds, settings pages) before tackling interactive screens with complex client state.

When to Bring in Help

If your team lacks native iOS or Android experience and you have custom native modules that need updating, or if you are more than one SDK version behind, the migration will be faster and less risky with experienced help. We have run this exact playbook across apps in fintech, e-commerce, healthcare, and media. The patterns are consistent, and the common pitfalls are avoidable when you know where to look.

Whether you are handling this migration in-house or looking for a partner to accelerate it, the important thing is to start. SDK 55 support ends in December 2031, and the longer you wait, the more the ecosystem moves ahead without you. If you want a second opinion on your migration plan, a dependency audit, or hands-on help with the upgrade, book a free strategy call and we will walk through your project together.

Need help building this?

Our team has launched 50+ products for startups and ambitious brands. Let's talk about your project.

Expo SDK 56 migration guideReact Server Components mobileExpo Router v5EAS Build performanceReact Native 0.84

Ready to build your product?

Book a free 15-minute strategy call. No pitch, just clarity on your next steps.

Get Started