Expo SDK releases are always interesting because they are not only about Expo packages.
An Expo SDK upgrade can also change:
React Native
iOS tooling
Android tooling
Expo Router
Native modules
Metro
Environment handling
Build configuration
EASExpo SDK 58 Beta is a good example.
The beta was released on September 15, 2026. It includes React Native 0.88 Release Candidate and is designed for developers who want to test the upcoming Expo release before the stable version arrives. Expo says the beta period will run for around three to four weeks.
For me, the important question is not only:
"What is new in SDK 58?"It is:
"What can break when I upgrade my existing app?"That is what I would focus on before moving a production application.
SDK 58 is built for iOS 27
One of the biggest reasons this beta is important is iOS 27.
Expo SDK 58 is built using the iOS 27 SDK, and iOS 27 requires the UIKit scene-based lifecycle. Expo has therefore moved Expo apps to the scene-based lifecycle so they can launch correctly on iOS 27.
This matters especially for applications with custom native iOS code.
A simple Expo application may not require much manual work.
But applications with:
Custom AppDelegate.swift
Native modules
Custom config plugins
Deep linking
Push notification handling
Handoff
Quick actions
Native lifecycle codeneed more careful testing.
The iOS lifecycle has changed
Older iOS applications commonly handled a lot of lifecycle work through:
AppDelegateWith the scene-based lifecycle, some responsibilities move into the scene lifecycle.
Expo SDK 58's prebuild process now generates:
SceneDelegate.swiftand adds the required scene configuration to Info.plist. The application window is also created by the scene delegate rather than directly in didFinishLaunchingWithOptions.
This is one of the first things I would check during an upgrade.
Especially when the project contains manually edited native files.
What if I have custom AppDelegate code?
This is where an Expo upgrade can become more complicated.
Suppose a project has custom code such as:
func application(
_ app: UIApplication,
open url: URL,
options: ...
)or custom lifecycle handling for:
Push notifications
Deep links
Quick actions
Universal links
Handoff
Third-party SDKsI would not assume that the old implementation can simply remain unchanged.
Expo says URL, user activity, Handoff, lifecycle and quick-action events are forwarded through ExpoAppDelegate overrides and subscribers, but developers who directly customize the AppDelegate or manage the ios directory manually should follow the scene lifecycle migration guidance.
This is exactly the kind of change that can appear only on a real iOS build.
Expo Go is not the same as a production build
This is an important point for beta testing.
Expo SDK 58 Beta is available through Expo CLI for Android devices/emulators and iOS simulators, and through eas go for iOS devices.
The App Store and Google Play versions of Expo Go are not moving to SDK 58 until around the stable release.
So I would not test a beta application only by opening the normal Expo Go app from the store.
For native functionality, a development build is much more useful.
For example:
npx expo prebuild --cleanThen:
npm run iosor:
npm run androidExpo also documents npx expo run for running native projects locally during the beta.
React Native 0.88 is inside SDK 58 Beta
SDK 58 currently includes React Native 0.88 Release Candidate.
That means an Expo SDK 58 upgrade is also effectively a React Native upgrade from the SDK 57 line.
Expo documents 0.88 as a release candidate inside the beta and highlights changes such as:
Swift Package Manager tooling
fontVariationSettings
ArrayBuffer in TurboModules
React Native DevTools improvementsThe stable React Native 0.88 release had not happened yet when SDK 58 Beta was announced.
This is another reason I would treat SDK 58 as a testing release rather than blindly upgrading a production application.
Expo Modules are getting faster
One of the interesting areas in SDK 58 is the native module layer.
Expo has reduced some of the overhead involved in communication between JavaScript and native code.
For iOS, SDK 58 makes calls that pass simple values cheaper, improves long-string transfers, and reduces the cost of creating and resolving promises for async functions. Expo reports that long-string transfers can be up to 3.8× faster in its measurements.
There is nothing special I need to do in my application to use these improvements.
Updating the Expo SDK means the newer Expo modules can take advantage of them automatically.
This is the kind of performance improvement I like because it does not require changing every screen.
Android builds can also become faster
Expo SDK 58 changes how expo-modules-core is distributed for Android.
Previously, a clean Android build could compile the native C++ library from source.
SDK 58 now ships precompiled libraries for the four Android ABIs in debug and release variants.
Expo measured a blank SDK 58 project with a clean Android debug build for all four ABIs at roughly:
Before:
~80 seconds
With prebuilt modules:
~39 secondsThat is roughly half the build time in their test environment. These are Expo's own measurements on an Apple M3 Pro, so actual results will vary by project and machine.
For developers working with CI, this can be more interesting than it first appears.
CI machines may have fewer CPU cores than a developer workstation, so removing unnecessary native compilation can reduce build time there as well.
Expo Modules 2.0 is in beta
SDK 58 also includes Expo Modules 2.0 Beta.
The idea is to make native module development more straightforward.
Instead of using the existing Expo Modules DSL, developers can write normal Swift or Kotlin classes and use annotations to expose methods and properties to JavaScript.
For example, the concept becomes closer to:
Swift / Kotlin class
↓
Annotations
↓
JavaScript APIrather than:
Custom module DSL
↓
Custom definition
↓
Generated bridgeI think this could be particularly interesting for developers who write custom native modules.
But because Expo Modules 2.0 is still beta, I would not migrate existing production modules just for the sake of using the newest API.
Test it first.
Fewer unnecessary native rebuilds
Another SDK 58 change is easy to miss but can be useful for development workflows.
Expo's fingerprint system now defaults to the:
balancedpreset.
This means some changes that previously caused the native fingerprint to change no longer necessarily trigger a new fingerprint.
For example, changing the app version or modifying files inside node_modules does not automatically mean a new fingerprint under the new default behaviour. Native modules are hashed using package name and version instead of their complete files and directories in common cases.
This can matter when using:
EAS Build
Development builds
Native rebuilds
CIFewer unnecessary native rebuilds can save time during daily development.
There is also an experimental Rust transformer
This is one of the more interesting performance experiments.
Expo SDK 58 includes an experimental transformer called:
NoxcturnalIt is written in Rust and uses Oxc for transformation.
Expo reports around:
3× faster per-module transform
2× faster cold bundlingin its internal testing. In one large test application with around 5,500 files, the cold bundle time was reported as:
Babel:
5.26 seconds
Noxcturnal:
2.46 secondsBut this feature is experimental and not available in every project configuration. Projects with custom Babel transforms or certain transforms such as Reanimated/Worklets may continue using Babel for affected files.
So I would test this rather than enabling it automatically everywhere.
Expo Router has important changes
Expo Router is another area developers should check.
SDK 58 makes several Router features stable:
Data loaders
Server-side rendering
Middleware
Native tabs
Toolbars
Standard navigation integrationThe navigation core itself has also been reworked so navigation state becomes more deterministic and less dependent on the forked React Navigation API.
Most applications may not notice this internally.
But applications with custom navigation code can.
Custom navigators need special attention
Expo specifically points out that some APIs have moved or been removed for projects using custom navigators or importing from:
expo-router/react-navigationSo I would search the codebase before upgrading.
For example:
grep -R "expo-router/react-navigation" .The exact command can be adjusted for the repository.
The important thing is to find these imports before the upgrade instead of discovering them after a deployment build fails.
Async routes on web
Expo Router also changes the default web behaviour.
SDK 58 enables:
asyncRoutesfor web by default.
Route files can now be split into separate JavaScript chunks, which the browser loads when the user navigates to those routes. Expo says the setting can be disabled with:
asyncRoutes: { web: false }when required.
This can be useful for larger Expo web projects.
Instead of loading the complete application JavaScript immediately:
Home
Products
Orders
Reports
Settingsthe browser can load route-specific chunks when required.
For a very large web application, this can improve the initial loading experience.
Screen-level error boundaries
Another useful Router feature is screen-level error boundaries.
Expo Router now allows fallback UI for a screen that throws while keeping the navigator mounted.
That is useful for larger applications where one screen should not necessarily destroy the complete navigation tree.
For example:
Dashboard
├── Orders
├── Products
└── ReportsIf the Reports screen fails, the application can potentially show an error state for that screen while the rest of the navigation continues to exist.
This is particularly useful for business applications.
Environment variables are changing
This is one of the changes I would test very carefully.
Expo CLI now sets NODE_ENV to either:
developmentor:
productionbefore loading .env files and the application config.
Previously, the inherited NODE_ENV behaviour could lead to different environment files being selected.
This matters if your project has:
.env
.env.local
.env.development
.env.development.local
.env.test
.env.test.localand custom app.config.js.
A project that relies on old NODE_ENV behaviour can behave differently after the upgrade.
This is something I would test before merging SDK 58.
Android R8 is enabled by default in release builds
SDK 58 also changes the Android template so R8 minification is enabled by default for release builds.
The setting is:
android.enableMinifyInReleaseBuilds=trueR8 can shrink, optimize and obfuscate Java/Kotlin code, reducing application size and potentially improving startup.
But libraries that depend on reflection may need ProGuard/R8 keep rules.
So one important test is:
Debug buildand:
Release buildDon't test only debug.
A release build with R8 can expose problems that never appear during development.
File System changes
Another breaking change is in expo-file-system.
File.write() is now asynchronous and returns a promise.
The previous synchronous behaviour is available through:
File.writeSync()instead.
So if an application contains:
File.write(...)I would inspect how the result is used.
For example, code that assumes the write has completed immediately may need to change.
This is a small API change but can create difficult bugs if it is hidden inside utility classes.
SQLite libSQL support is removed
Another thing to check is expo-sqlite.
SDK 58 removes libSQL support, including:
syncLibSQL()
libSQLOptionsThose APIs are no longer available.
Applications using Expo SQLite should therefore check whether they actually depend on this functionality.
This is exactly the kind of dependency-specific breaking change that can be missed when someone only reads the top-level SDK announcement.
Notifications behaviour changes
Notifications also have an important change.
On iOS, foreground notifications are now shown by default unless the application's notification handler says otherwise.
This means an application that previously relied on different foreground notification behaviour should explicitly check its notification handler after upgrading.
For a business application, I would test:
App foreground
App background
App killed
Notification tap
Deep link from notification
Multiple notifications
Notification groupingPush notifications should always be tested on real devices.
Android widgets are now part of the story
Expo SDK 58 also expands home-screen widget support to Android through expo-widgets.
The Android widgets use a dedicated Hermes runtime and support interactions and Material Colors.
This opens some interesting possibilities.
For example:
Order status
Today's sales
Pending tasks
Calendar events
Delivery status
Quick actionscan potentially be surfaced outside the main application.
This is particularly interesting for productivity and business applications.
App Intents are coming to Expo
SDK 58 also includes an alpha package:
expo-app-intentswhich exposes Apple's App Intents functionality to Expo applications.
That connects Expo apps with:
Siri
Shortcuts
Spotlight
Apple IntelligenceThe API is still in alpha, so I would treat it as an experimental feature for now.
But the use cases are interesting.
Imagine an application where the user can say:
"Mark my task as completed."and Siri can ask which task before invoking the application action.
Expo's SDK 58 announcement demonstrates this exact type of task-completion workflow.
Variable fonts are supported
expo-font also adds support for variable fonts across:
Android
iOS
WebA single font file can provide several weights or styles rather than requiring separate font files for every variation.
This can be useful for applications that want:
Regular
Medium
Semi-bold
Boldwithout maintaining many separate font files.
Again, this is a feature to use when there is a real UI requirement.
Expo 58 and development behind proxies
Another change I like from a practical development perspective is improved handling when the development server is:
Behind a proxy
On another machine
Behind a tunnelExpo now uses relative URLs in development manifests when supported, which can help development builds connect more reliably to servers behind proxies or Bonjour-related network discovery problems.
The CLI also improves port handling.
For developers running multiple projects at once, this can remove some annoying development-server problems.
The new Expo tunnel
Expo CLI also has a new tunnel implementation.
Expo says the new tunnel connects faster and holds connections more reliably and no longer needs @expo/ngrok.
For example, developers working across:
Laptop
Physical Android phone
Physical iPhone
Different Wi-Fi networks
Remote developmentcan benefit from reliable development connectivity.
The tunnel requires signing into an Expo account.
Node.js requirements
SDK 58 also raises the tooling requirements.
Expo documents support for:
Node.js 22.13+
Node.js 24.3+
Node.js 26+while odd-numbered releases such as Node 23 and 25 are not supported by the SDK tooling.
This matters for CI.
It is common to have:
Developer laptop → Node 24
CI → Node 20and then discover that the project works locally but fails during the build.
I always prefer checking the exact Node version in:
Local
CI
EAS
Docker
Build serverbefore an SDK upgrade.
How I would upgrade an existing Expo project
I would not immediately run a beta upgrade on the main branch.
I would create a dedicated branch:
git checkout -b upgrade-expo-sdk-58Then upgrade the Expo dependencies according to the beta instructions.
Expo currently recommends:
npx expo install expo@next --fixfor trying the SDK 58 beta.
After dependency installation, I would check:
npx expo-doctorand then inspect the native projects.
For a prebuild-based project:
npx expo prebuild --cleanThen test:
npx expo run:androidand:
npx expo run:iosor the equivalent npm run scripts configured by the project. Expo documents these native testing steps for the beta.
I would test more than the home screen
For a serious application, my test list would include:
Login
Registration
Navigation
API calls
Authentication
Push notifications
Deep links
File uploads
Camera
Location
Local storage
SQLite
Background tasks
Payments
PDF generation
Notifications
Offline behaviourThen:
Android debug
Android release
iOS debug
iOS releaseThis is especially important because SDK 58 changes native build behaviour in several places.
Test the application after a clean install
A common mistake is testing only an application that is already installed.
I also test:
Fresh installation
Existing application upgrade
App data retained
App data migration
Permissions
Notifications
Deep linksThe upgrade path can expose problems that a clean installation hides.
For example, an existing user may already have:
Old AsyncStorage data
Old database schema
Old permissions
Old notification tokens
Old cached filesThe new version has to handle those states.
Test the release build, not just Expo Go
This is especially important for Expo applications that use native modules.
Expo Go cannot represent every possible production configuration.
A project may use:
Custom native module
Custom config plugin
Custom native dependency
Special permissions
Custom app delegate codeIn those cases, a development build or release build is more representative of production.
For SDK 58, this becomes even more important because of the iOS 27 lifecycle changes and Android R8 changes.
Should a production app use the beta?
I would separate two questions.
For a new experimental application:
SDK 58 Betacan be useful for testing the upcoming ecosystem.
For an existing production application:
Current stable SDKis generally easier to control until SDK 58 becomes stable.
The reason is simple.
The beta exists specifically so developers can find regressions and report them before the stable release. Expo says the beta will continue receiving fixes and improvements during the testing period.
So I would treat the beta as a testing opportunity rather than automatically making it the production baseline.
My SDK 58 upgrade checklist
Before merging an SDK 58 upgrade, I would check:
✓ Node.js version
✓ Expo dependencies
✓ React Native version
✓ React version
✓ app.config.js
✓ .env behaviour
✓ Expo Router imports
✓ Custom navigators
✓ AppDelegate.swift
✓ SceneDelegate behaviour
✓ Deep links
✓ Notifications
✓ File system usage
✓ SQLite usage
✓ Native modules
✓ Config plugins
✓ Android R8
✓ Android release build
✓ iOS release build
✓ CI
✓ EAS Build
✓ Fresh installation
✓ Existing app upgradeThis list is much more important to me than simply seeing:
"npm install completed successfully."Final thoughts
Expo SDK 58 Beta is a significant release because many changes happen underneath the normal React Native application code.
The application screens can remain almost exactly the same while the development and native infrastructure changes considerably.
The biggest things I would watch are:
iOS 27 scene lifecycle
React Native 0.88
Expo Router changes
Environment variable behaviour
Android R8
Expo Modules
File System changes
SQLite changes
Notifications
Build performanceThere are also several interesting new capabilities such as Android widgets, App Intents, variable fonts and better native build performance.
The performance improvements are also interesting.
Prebuilt Android Expo modules can reduce clean build time, Expo reports faster native module calls, and the experimental Rust transformer can significantly reduce cold bundling time in its internal tests.
But I would still approach SDK 58 Beta as a testing release.
For me, the right upgrade process is:
Create branch
↓
Upgrade dependencies
↓
Check migration changes
↓
Test native code
↓
Test Android
↓
Test iOS
↓
Test release builds
↓
Test CI / EAS
↓
Fix regressions
↓
Move to stableAn Expo upgrade should not be measured only by whether the application opens.
A successful upgrade means the complete application still works across the JavaScript layer, native layer, build system and production environment.
That is where most of the real upgrade work is.