Expo Release Notes
25 release notes curated from 29 sources by the Releasebot Team. Last updated: Oct 16, 2026
- Oct 15, 2026
- Date parsed from source:Oct 15, 2026
- First seen by Releasebot:Oct 16, 2026
Expo SDK 58
Expo releases SDK 58 with React Native 0.88, iOS 27 and foldable-device support, stable Expo Router features, Android home screen widgets, and faster native builds. The update also expands Expo UI, adds agent-focused tools, and brings a wide range of improvements across the ecosystem.
Today we're announcing the release of Expo SDK 58. SDK 58 is built for iOS 27 and includes React Native 0.88. Thank you to everyone who helped with beta testing.
Note: Expo Go for SDK 58 on the Apple App Store and Google Play Store will be released within a few weeks.
SDK 58 is built for iOS 27
iOS 27 requires the UIKit scene-based life cycle and makes iPhone apps resizable, and apps built with the iOS 27 SDK get both automatically. Expo apps use the scene-based life cycle so they launch correctly on iOS 27. This changes how app delegate callbacks are delivered, so read the scene life cycle migration guide if you customize AppDelegate.swift. Expo packages no longer read geometry from UIScreen.main, and expo-modules-core has scene-aware geometry helpers.
On iOS 27, requireFullScreen no longer opts your app out of resizing, and ScreenOrientation.lockAsync may have no effect while the app is resizable. The requireFullScreen config plugin is updated for this. See Orientation locks on iOS 27 and later. expo-glass-effect reports isLiquidGlassAvailable as true in apps built with the iOS 27 SDK.
iPhone Duo support
Apps built with SDK 58 are ready for iPhone Duo on the day it is released. On iPhone Duo, iOS moves most bars and controls into a vertical rail on the right or left edge. Your app will also need to respond to changes in window size as the device is folded or an app is shown in split view on the inner display. Start with the basics:
- Navigation: Use Expo Router's Stack and NativeTabs, or SwiftUI views through Expo UI's . They use the system's own navigation and tab bars, which iOS places for you on both displays.
- Safe areas: Safe area handling becomes more important, and you may need to add in more places, such as inside scrollviews, to handle horizontal insets for iPhone Duo. Update react-native-safe-area-context to the latest version via npx expo install react-native-safe-area-context.
Module authors who present popovers can use the new SceneGeometry.anchorPopover helper in expo-modules-core to anchor them correctly on any regular-width display.
For layout, Expo UI adds ArrangementView, the SwiftUI container Apple recommends for iPhone Duo. It places a primary and a secondary view side by side or as an overlay, and adapts to the fold and the device pose.
To react to the hinge itself, use the new expo-hinge package. useHinge(), getHinge(), and addHingeListener() report the hinge angle and whether it is closed, partially open, or fully open, on iOS 27.1 and later and on Android 11 foldables. In SwiftUI, the onHingeChange modifier does the same for a single view, and a callback from useWorkletCallback runs on the UI thread to keep effects such as parallax smooth. Apple recommends hinge state for interactions and effects, such as a tabletop camera shutter, not for layout.
Device Hub support for Xcode 27
Xcode 27 replaces Simulator.app with Device Hub. Expo CLI detects Device Hub, boots simulators through it, and focuses the right device using its devices:// deep link. If you'd rather not leave your editor, the new expo-device-hub dev tools plugin turns your browser into a local device dashboard: a live stream of every iOS simulator and Android emulator that you can tap, swipe, and type into; boot and shutdown controls; CPU, memory, and network graphs; and toggles for appearance, Liquid Glass, text size, and accessibility settings. Install it with npx expo install expo-device-hub, run npx expo start, and the link prints in your terminal. If you want the same experience without a local Xcode or Android Studio install, keep an eye on EAS Simulator, our upcoming service for cloud simulators.
App Intents: expose your app to Siri and Apple Intelligence
expo-app-intents exposes your app’s actions and content to Siri, Shortcuts, Spotlight, and Apple Intelligence. Declare intents in Swift inline modules in an app-intents directory so Apple can discover them in the app target at build time. The package delivers invocations to JavaScript and stores entity data you update from JavaScript. Run npx expo-app-intents init to set up app-intents in your app. If you use coding agents, run npx @expo/agent-cli@latest install expo-app-intents to install the agent skill. The library is in alpha.
The package also supports Spotlight indexing, intent donations for system suggestions, and identifying on-screen content with appEntityIdentifier() for Expo UI or AppEntityView for React Native. On-screen identification requires iOS 18.4 or later and Xcode 27 or later.
A version coming soon will support running expo-task-manager tasks from intent handlers, so you can perform work in JavaScript and return a result to Siri without opening your app.
Example: completing a task from Siri
For example, an onboarding checklist app can let Siri list its tasks and ask which one to complete.
Expo UI: recycling lists, native navigation on iOS, new Compose components, and more
Recycling lists for large data sets
List, LazyVStack and LazyHStack on iOS, and LazyColumn and LazyRow on Android now virtualize and recycle rows. Instead of rendering every row up front, they render only the rows near the visible area and reuse them as you scroll.
Pass the items as data, a unique key for each item with keyExtractor, and a children function that returns the row. Use List.ForEach, LazyVStack.ForEach and LazyHStack.ForEach in SwiftUI, and LazyColumn.Items and LazyRow.Items in Jetpack Compose.
Every component now has a visual in the docs
The Expo UI reference now shows a screenshot of every component next to its API, so you can see what you're picking before you read the props. Browse the SwiftUI and Jetpack Compose galleries in the docs.
iOS navigation
@expo/ui adds NavigationStack, Toolbar, NavigationLink and NavigationDestination components, the navigationTitle modifier, and the close button role. NavigationSplitView adds two- and three-column layouts, and ToolbarItem takes placement and visibilityPriority.
SwiftUI
The background, tint, border, strokeBorder, containerBackground, presentationBackground and foregroundStyle modifiers now accept any ShapeStyle, so a view can be painted with a material or a gradient. Also new: the Background component and the scrollClipDisabled, geometryGroup, listRowSeparatorTint, alignmentGuide, menuStyle, menuIndicator, and scrollEdgeEffectStyle modifiers.
Jetpack Compose
New Image, DateRangePicker, DateRangePickerDialog and VerticalSlider components. DropdownMenu gains cornerRadius and shadowElevation, and RadioButton gains enabled and colors.
Universal components
BottomSheet adds contentPadding, containerColor and contentColor, and ListItem takes a colors prop. On web, BottomSheet drops the unmaintained vaul for an in-house HTML .
Hosted React Native views
Views inside are now measured where SwiftUI and Jetpack Compose place them, so measure() returns correct values and touches work inside BottomSheet, Popover, AlertDialog and DropdownMenu. Tapping outside a hosted text field dismisses the keyboard, and closing a SwiftUI Menu no longer presses the view underneath it.
Expo Observe
Expo Observe monitors your app in production. It records startup and navigation performance, JavaScript errors, and native crashes from your users' devices, and compares each release with all your releases so you can catch regressions early. In SDK 58, expo-observe adds an errorHandlingEnabled option to turn off automatic recording of unhandled JavaScript errors and exposes Observe.clientId so you can match Observe data with other tools. AppMetrics is deprecated in favor of Observe; see Deprecations.
Agentic development with Expo CLIs
Expo CLI now has updated help text and new commands that work better with agent harnesses. You may see your agent invoking npx expo command:ps and npx expo command:events, which give it machine-readable information about running Expo processes and their event logs. This helps it understand the state of its own and other Expo dev servers. These commands are experimental. We'll expand them over time and adjust their output to better support automated use of Expo CLI.
We've used this system throughout SDK 58's development, and it has also helped us profile, debug, and improve Expo CLI internally. We've observed that giving agents awareness of all running Expo commands and their events helps them use Expo CLI more reliably and consistently. This replaces our old debug logging, which means you'll see a change in output when you debug Expo CLI yourself with EXPO_DEBUG=1.
However, these improvements haven't been enough on their own, so we're also introducing a CLI primarily aimed at agentic development.
@expo/agent-cli: the new CLI designed for agents
Agents used to learn Expo the hard way: launch Expo Go and hit a runtime error if you add a native module Expo Go doesn't support, then guess that they need a development build. They also had to know when to use Expo CLI and when to use EAS CLI. @expo/agent-cli is a new experimental CLI, built by agents and designed for agents. It sits on top of Expo CLI, EAS CLI, and expo-doctor, and falls back to Expo CLI, so you can ask your agent to use it as a replacement.
Some useful commands you can try: status answers Expo Go compatibility without starting the app. dev starts the app with one command, like a web framework starting a server and a browser. It takes care of when to build the app and tries the fastest way to get your app running. Commands print next steps, so agents know how to move on. smoke is dev, plus a screenshot, plus stop: it checks that you can actually start developing the app on your machine. skills:sync sets up co-located agent skills from node_modules in your project.
Start with npx @expo/agent-cli@latest agents:setup, then tell your agent to use @expo/agent-cli instead of Expo CLI.
If you prefer a shorter name, expo-agent-cli is available as an alias. This CLI is under active development, and we'll go into more detail in an upcoming blog post.
Home screen widgets come to Android
expo-widgets adds an Android implementation: widgets run their own JS bundle on a dedicated Hermes runtime, with support for interactions and Material Colors. Android widgets also support the cornerRadius modifier. On iOS, Live Activities gain a staleDate option on LiveActivity.start() and update(), stable ActivityKit identifiers, and runtime widget configuration changes.
Swift Package Manager builds
React Native 0.87 added experimental Swift Package Manager support as an alternative to CocoaPods, and SDK 58 lays the groundwork for Expo apps to use it. Expo's iOS sources have been restructured so their Swift, Objective-C, and C++ compile as separate SwiftPM targets, and an Expo autolinking plugin for React Native's npx react-native spm pipeline is available as a preview. CocoaPods remains the default and supported path, and precompiled Expo modules keep working there.
Expo Modules: faster builds, faster calls, simpler to write
Faster Android builds with prebuilt expo-modules-core
expo-modules-core now ships precompiled native libraries for Android. Previously, every clean build, CI run, and EAS Build compiled the C++ in libexpo-modules-core.so from source. The npm package now includes .so files for all four ABIs in debug and release variants. In our test on a blank SDK 58 project, a clean Android debug build for all four ABIs took about 80 seconds on an Apple M3 Pro. Skipping the expo-modules-core C++ compilation cut it to about 39 seconds, roughly half. To compile the libraries from source instead, set android.buildExpoModulesCoreFromSource with expo-build-properties.
Faster Expo modules
A native module call isn't free. There's a fixed cost to crossing into Swift or Kotlin and converting the values that go each way. SDK 58 takes another pass at the iOS side. Calls that pass or return simple values are cheaper, passing long strings in either direction is up to 3.8× faster, and promises from async functions cost less to create and resolve. There's nothing to adopt: update to SDK 58 and every Expo module gets faster.
Expo Modules 2.0 beta
Instead of describing your native module inside the existing DSL definition, you can now write an ordinary Swift or Kotlin class and annotate the methods and properties you want to expose to JavaScript. It's a much better fit for coding agents too. On the same SDK, synchronous calls are 2.5 to 5.6× faster than the DSL. On Android, Expo Modules 2.0 is faster than Expo Modules 1.0 in every measured microbenchmark and faster than a TurboModule in every case. With SDK 58, Expo Modules 2.0 is in beta on both iOS and Android.
Fewer unnecessary native rebuilds with the new fingerprint default
Bumping a version, or changing files inside node_modules, no longer means a new fingerprint. SDK 58 defaults fingerprint to the balanced preset. It ignores common cases like updating version in app.json, and hashes native modules by package name and version instead of their files and directories.
Experimental: 2× faster cold bundling with a Rust-based transformer
SDK 58 introduces an experimental replacement for Babel: "Noxcturnal", a module transformer written in Rust on top of oxc and exposed to Node.js through napi-rs. Per-module transform time was about 3× faster and end-to-end cold bundling about 2× faster. Try it by setting experiments.noxcturnalTransformWorker in your app config.
Expo Router: stable data loaders and native tabs, improved core
Data loaders, server-side rendering, and middleware are now stable and no longer need experimental flags. Native tabs, toolbars, and the standard navigation integration are also stable. Expo Router's navigation core has been reworked so navigation state is deterministic and easier to reason about. Other changes include platform HTTP-cache loader responses, server output by default, async routes on web by default, React transitions and activities, custom router APIs, screen error boundaries, changed web safe-area handling, optional dependencies, and an experimental PerformanceObserver analytics API.
Connecting to dev servers through proxies and tunnels
If you run your dev server behind a proxy, on a remote machine, or over a tunnel, development builds should now connect to it reliably. The manifest now uses relative URLs when the client supports them. Prebuild writes the port to the RCTMetroPort key in Info.plist, Expo CLI port selection is more consistent, and non-interactive runs roll over to the next free port instead of failing.
A faster, more reliable Expo CLI tunnel
Expo CLI has a new tunnel implementation built on @expo/ws-tunnel. It connects faster, holds the connection more reliably, and no longer needs @expo/ngrok. This is now the default when running expo start with a tunnel. Use expo start --tunnel; you'll need to be signed in to your Expo account. Legacy @expo/ngrok tunnels remain available with --tunnel ngrok.
React Native 0.88
SDK 58 upgrades React Native from 0.86 to 0.88. Highlights include Swift Package Manager tooling, fontVariationSettings on Text, ArrayBuffer in TurboModules, and React Native DevTools improvements.
PostHog integration
You can now set up PostHog in an Expo app with one command. Run eas integrations:posthog:connect and EAS CLI creates or links your PostHog project, installs the SDK and its config plugin, and writes the environment variables to your project and to EAS. Events include EAS update, build, channel, and runtime version properties.
Launch URLs for development builds and Expo Go
Development builds and Expo Go now share one launch URL contract. Query parameters beginning with _expo are launcher commands. Supported parameters include __expo_url, __expo_disable_onboarding=1, __expo_disable_fab=1, and __expo_disable_auto_launch=1. expo-linking and Expo Router ignore the reserved parameters, and expo-linking exports unwrapDevLaunchURL().
Other notable changes
- expo-camera: added CameraView.scanDocumentAsync for multi-page document scanning on Android and iOS.
- expo-file-system: added File.digest() for MD5/SHA-1/SHA-256/SHA-384/SHA-512 hashes, and File.preview() and File.canPreview() for native preview flows.
- expo-audio: added lock screen controls with playlists and WAV/PCM file recording.
- expo-image: added transition.skipOnCacheHit and svgVariables support.
- expo-secure-store: added requireConfirmation on Android for authenticated reads and writes.
- expo: URL and URLSearchParams were rewritten with IDNA/TR-46 support, and TextDecoder was rewritten for speed.
- expo-sqlite: ships a co-located agent skill, interruptSync(), and configureWeb() for loading a custom wa-sqlite WebAssembly build.
- expo-font: added variable font support across Android, iOS, and web.
- expo-notifications: improved iOS delegate coexistence and Android alarm-clock delivery.
- expo-location: introduced the experimental expo-location/next API and changed iOS geofencing requirements.
- @expo/metro-config: EXPO_PUBLIC_* environment variables are recorded in the transform cache, and node_modules stack frames are no longer collapsed.
- @expo/log-box: LogBox now shows the call stack and code frame even when every frame is collapsed.
- @expo/cli: improved Android virtual-device management, Xcode error output, and collapsed error stacks.
- expo-updates: added updates.maxUpdatesToKeep.
Deprecations
Deprecated items include expo-file-system File.md5, expo-modules-core NativeArrayBuffer, expo-observe AppMetrics, expo-router withLayoutContext, expo-sqlite useLibSQL, and several @expo/ui properties and APIs.
Notable breaking changes
React Native 0.87 makes the Strict TypeScript API the default and removes several APIs. SDK 58 does not support macOS yet. The iOS 27 SDK requires the UIScene life cycle. Expo CLI changes NODE_ENV handling and environment-file loading. R8 is enabled by default in Android release builds. Expo Router's navigation core and server-output defaults have changed. File.write() is now async; libSQL support was removed from expo-sqlite; foreground notifications are shown by default; the @expo/fingerprint default preset is balanced; and there are additional breaking changes across @expo/ui, expo-localization, expo-media-library, @expo/cli, and other packages.
Tool version bumps
Expo tooling now requires Node.js 22.13 or newer on the 22 line, 24.3 or newer on the 24 line, or Node.js 26 and later. Expo modules tooling is compatible with AGP 9. @expo/ui and the Expo module template use Compose UI and Foundation 1.12.1 and Material 3 1.5.0-beta01.
Expo Go
The new Expo Go will be released on the App Store and Google Play within a few weeks. Until then, npx create-expo-app creates SDK 57 projects. To start a new SDK 58 project, run npx create-expo-app --template default@sdk-58 and use a development build. The new Expo Go will support only SDK 58.
Upgrading your app
Upgrade dependencies with npx expo install expo@^58.0.0 --fix, run npx expo-doctor@latest, review the Deprecations and Notable breaking changes sections, and follow the migration guidance for scene-based iOS life cycle, native projects, development builds, and Expo Go.
Thanks to everyone who contributed to the release!
Original source - Oct 14, 2026
- Date parsed from source:Oct 14, 2026
- First seen by Releasebot:Oct 15, 2026
Refreshed settings navigation on expo.dev
Expo redesigns user, account, and project settings with dedicated pages and consistent sidebars, making security, connections, notifications, billing, credentials, and other options easier to find.
User, account, and project settings have a new design, with dedicated pages and a consistent sidebar to make settings easier to find.
- User settings: a refreshed General page, Authentication for sign-in methods and two-factor configuration, a standalone Security page, and an Advanced page for renaming and deletion.
- Account settings: a refreshed General page, and standalone Connections, Security, and Advanced pages. Billing, Receipts, Access Tokens, and Notifications have moved from the app-wide account sidebar into the account settings sidebar.
- Project settings: a refreshed General page, with dedicated Notifications, Connections, and Advanced pages. Credentials, Hosting, and GitHub have moved from the app-wide project sidebar into the project settings sidebar.
To view the new changes, visit the User Settings page and the account and project settings via the Settings sidebar entry on an account or project.
Original source All of your release notes in one feed
Join Releasebot and get updates from Expo and hundreds of other software products.
- Oct 7, 2026
- Date parsed from source:Oct 7, 2026
- First seen by Releasebot:Oct 7, 2026
Native crash reporting in Expo's Observability service
Expo adds native crash reporting to EAS Observe, bringing Android and iOS crashes into the same error view as JavaScript issues with no setup. It also adds filtering, crash-free session insights, detailed crash context, and Hand off to AI for quick fixes.
EAS Observe now records native crashes alongside JavaScript errors. Update to 57.0.21 or later on SDK 57.
Until now, the Errors page showed only what went wrong in your JavaScript. A crash in native code took the app down without a trace. Now expo-observe records those too, on both Android and iOS, with no setup. Update to 57.0.21 or later on SDK 57.
On Android, this covers uncaught Java and Kotlin exceptions, plus the crash records the operating system keeps for your app on Android 11 and later. On iOS, it covers Mach exceptions such as EXC_BAD_ACCESS, Unix signals such as SIGSEGV, and uncaught Objective-C and Swift exceptions.
Native crashes land in the same list as your JavaScript errors. Filter by source to see one or the other, and watch crash-free sessions for the overall picture. Open a crash to see its stack trace, the session records that led up to it, and a breakdown by app version, OS, device, and country.
Ready to fix it? Select Hand off to AI on the error details page to send the crash and its context straight to Claude Code or Codex.
Error reporting is in preview.
Read the error reporting docs.
Original source - Sep 15, 2026
- Date parsed from source:Sep 15, 2026
- First seen by Releasebot:Sep 17, 2026
Expo SDK 58 Beta is now available
Expo releases SDK 58 beta with iOS 27 support, React Native 0.88 RC, faster Expo Modules, stable Expo Router data loaders and native tabs, new Expo UI navigation and Compose components, Android widgets, Device Hub support, and several performance and tooling improvements.
SDK 58 beta period
The SDK 58 beta period begins today and will last three to four weeks. The beta is an opportunity for developers to test out the SDK and ensure that the new release does not introduce any regressions for their particular systems and app configurations. We will be continuously releasing fixes and improvements during the beta period.
SDK 58 is built for iOS 27, and you can ship with the beta if you want iOS 27 support in your app now. SDK 58 beta includes React Native 0.88 (Release Candidate). React Native 0.88 has not been released yet, so the beta uses the release candidate. We will move to the stable release when React Native 0.88 ships, and release SDK 58 shortly after. The full release notes for SDK 58 won't be available until the stable release, but you can browse the changelogs in the expo/expo repository to learn more about the scope of the release and any breaking changes. We'll merge all changelogs into the root CHANGELOG.md when the beta is complete.
Expo Go for SDK 58 is available today only through Expo CLI, for Android devices and emulators and iOS simulators, and through eas go for iOS devices (learn more). The App Store and Google Play versions of Expo Go will update to SDK 58 shortly after the stable release, so you have time to upgrade before the store version drops SDK 57 support.
We're also hosting office hours on Discord for those of you interested in helping test the release!
SDK 58 is built for iOS 27
SDK 58 is built for iOS 27
iOS 27 requires the UIKit scene-based life cycle and makes iPhone apps resizable, and apps built with the iOS 27 SDK get both automatically. Expo apps now use the scene-based life cycle so they launch correctly on iOS 27 (#46733). This changes how app delegate callbacks are delivered, so read the scene life cycle migration guide if you customize AppDelegate.swift. Expo packages no longer read geometry from UIScreen.main (#48172, #48315, #48316, #48170, #48169), and expo-modules-core has scene-aware geometry helpers (#48168).
On iOS 27, requireFullScreen no longer opts your app out of resizing, and ScreenOrientation.lockAsync may have no effect while the app is resizable. The requireFullScreen config plugin is updated for this (#48175). See Orientation locks on iOS 27 and later.
expo-glass-effect reports isLiquidGlassAvailable as true in apps built with the iOS 27 SDK (#49850).
We'll also ship improvements during the beta to ensure deep integration with iPhone Duo from day one, as soon as the iPhone Duo SDK is available to developers.
EAS Build images with Xcode 27 and with the SDK 58 toolchain are coming soon, and we'll update this post when they're available. Until then, the latest EAS Build image ships Xcode 26.6.
Device Hub support for Xcode 27
Xcode 27 replaces Simulator.app with Device Hub. Expo CLI detects Device Hub, boots simulators through it, and focuses the right device using its devices:// deep link (#46757, #46809). If you'd rather not leave your editor, the new expo-device-hub dev tools plugin turns your browser into a local device dashboard: a live stream of every iOS simulator and Android emulator that you can tap, swipe, and type into, boot and shut down controls, CPU, memory, and network graphs, and toggles for appearance, Liquid Glass, text size, and accessibility settings. Install it with npx expo install expo-device-hub, run npx expo start, and the link prints in your terminal. If you want the same experience without a local Xcode or Android Studio install, keep an eye on EAS Simulator, our upcoming service for cloud simulators.
App Intents: expose your app to Siri and Apple Intelligence
expo-app-intents exposes Apple App Intents (Siri, Shortcuts, Spotlight, and Apple Intelligence) from Expo apps (#47207). App Intent types are declared in Swift inline modules in an app-intents directory, since Apple's build-time metadata extraction only sees code in the app target. The package delivers invocations to JavaScript and stores entity values. Run npx expo-app-intents init to set up the directory (#47223). This library is in alpha, and documentation and examples are coming soon.
Example: completing a task from Siri
An onboarding checklist app declares a "complete task" intent and a task entity. Ask Siri to complete a task, and Siri lists the tasks from the app and asks which one. Pick one, and the intent runs in your JavaScript and the app marks it done, all without foregrounding the app.
Expo UI: native navigation on iOS, new Compose components, and more
Every component now has a visual in the docs
The Expo UI reference now shows a screenshot of every component next to its API, so you can see what you're picking before you read the props. Browse the SwiftUI and Jetpack Compose galleries in the docs.
iOS navigation.
@expo/ui adds NavigationStack, Toolbar, NavigationLink, and NavigationDestination components, the navigationTitle modifier, and the close button role (#49940, #49991). NavigationSplitView adds two and three-column layouts (#50075).
SwiftUI.
The background, tint, border, strokeBorder, containerBackground, presentationBackground, and foregroundStyle modifiers now accept any ShapeStyle, so a view can be painted with a material or a gradient (#48905, #49621, #49767, #49838). Also new: the Background component (#48904) and the scrollClipDisabled (#49780), geometryGroup (#48838), listRowSeparatorTint (#48810), alignmentGuide (#49247), menuStyle, and menuIndicator (#48448) modifiers.
Jetpack Compose.
New Image (#48521), DateRangePicker, DateRangePickerDialog (#49788) and VerticalSlider (#49612) components. DropdownMenu gains cornerRadius and shadowElevation (#49515, #49896), and RadioButton gains enabled and colors (#49852).
Universal components.
BottomSheet adds contentPadding, containerColor, and contentColor, and ListItem takes a colors prop (#48902, #49575). On web, BottomSheet drops the unmaintained vaul for an in-house HTML (#49509).
Hosted React Native views.
Views hosted inside are now measured where SwiftUI and Jetpack Compose placed them (#48969, #48970). This fixes dropped presses, gestures stolen from an enclosing scrollable, and missing touches inside BottomSheet, Popover, AlertDialog, and DropdownMenu. Tapping outside a hosted text field now dismisses the keyboard (#48788). The tap that closes a SwiftUI Menu no longer presses the React Native view underneath it (#48463, #49775).
Expo and EAS Observe
EAS Observe monitors your app's performance and errors in production, and it has been generally available since August 20. In SDK 58, expo-observe adds Observe.registerIntegration (#48245), ObserveErrorBoundary, and reportError (#47341, #47871), the errorHandlingEnabled option (#48506), an expo-image integration (#47145), and Observe.clientId, the EAS client ID recorded on every event (#49599). AppMetrics is deprecated in favor of Observe — see Deprecations.
@expo/agent-cli: the new CLI designed for agents
Agents used to learn Expo the hard way: launch Expo Go and hit a runtime error if you add a native module Expo Go doesn't support, then guess to use a development build. They also had to know when to use Expo CLI and when to use EAS CLI.
@expo/agent-cli is a new experimental CLI, built by agents and designed for agents. It sits on top of Expo CLI, EAS CLI, and expo-doctor, and falls back to Expo CLI, so you can ask your agent to use it as a replacement.
Some useful commands you can try:
status answers Expo Go compatibility without starting the app.
dev starts the app with one command, like a web framework starting a server and a browser. It takes care of when to build the app and tries the fastest way to get your app running. Commands print next steps, so agents know how to move on.
smoke is dev, plus a screenshot, plus stop: it checks that you can actually start developing the app on your machine.
skills:sync sets up co-located agent skills from node_modules in your project.Start with npx @expo/agent-cli@latest agents:setup, then tell your agent to use @expo/agent-cli instead of Expo CLI.
If you prefer a shorter name, expo-agent-cli is available as an alias. Thanks to Kazutoyo Tokai for transferring the package name to us. This CLI is under active development, and we'll go into more detail in an upcoming blog post. In the meantime, try it out and let us know what you think.
Home screen widgets come to Android
expo-widgets adds an Android implementation: widgets run their own JS bundle on a dedicated Hermes runtime, with support for interactions and Material Colors (#46961, #47035, #48454). On iOS, Live Activities gain a staleDate option on LiveActivity.start() and update() (#46343), stable ActivityKit identifiers (#48589), and runtime widget configuration changes (#47533).
Swift Package Manager builds
React Native 0.87 added experimental Swift Package Manager support as an alternative to CocoaPods, and SDK 58 lays the groundwork for Expo apps to use it. Expo's iOS sources have been restructured so their Swift, Objective-C, and C++ compile as separate SwiftPM targets (#45906, #49820, #49821, #49832), and an Expo autolinking plugin for React Native's npx react-native spm pipeline is in review (#49823). We plan to publish it as a preview during the beta. CocoaPods remains the default and supported path, and precompiled Expo modules keep working there.
Expo Modules: faster builds, faster calls, simpler to write
Faster Android builds with prebuilt expo-modules-core
expo-modules-core now ships precompiled native libraries for Android. Previously, every clean build, CI run, and EAS Build compiled the C++ in libexpo-modules-core.so from source, the most expensive step of an Android build that uses Expo. The npm package now includes .so files for all four ABIs in debug and release variants. In our test on a blank SDK 58 project, a clean Android debug build for all four ABIs took about 80 seconds on an Apple M3 Pro. Skipping the expo-modules-core C++ compilation cut it to about 39 seconds, roughly half. The saving is larger on machines with fewer cores, such as CI runners. The removed compiler work adds up to over 10 minutes across the four ABIs, which a 12-core machine hides by running many files in parallel.
Faster Expo modules
A native module call isn't free. There's a fixed cost to crossing into Swift or Kotlin and converting the values that go each way, and on the cheap calls that's most of what you're paying for. SDK 56 went after this on both platforms: we dropped the Objective-C++ layer on iOS to make calls 1.6 to 2.3× faster, and replaced reflection with a Kotlin compiler plugin on Android, making Record conversion around 6× faster and cutting time to first render by roughly 30%.
SDK 58 takes another pass at the iOS side. Calls that pass or return simple values are cheaper (#49761), passing long strings in either direction is up to 3.8× faster (#49678), and promises from async functions cost less to create and resolve (#49718). There's nothing to adopt: update to SDK 58 and every Expo module gets faster, including the ones you didn't write.
Expo Modules 2.0 beta
The other half of the story is the API you write against. Instead of describing your native module inside the existing DSL definition, you can now write an ordinary Swift or Kotlin class and annotate the methods and properties you want to expose to JavaScript. There's nothing new to learn beyond a handful of annotations. It's a much better fit for coding agents too, since there's no custom DSL to explain first. It's just Swift and Kotlin, which models already know well.
It's faster again on top of the improvements above, since the annotations let us generate the most direct binding at build time instead of figuring one out at runtime. On the same SDK, synchronous calls are 2.5 to 5.6× faster than the DSL, measured on an iPhone 16 Pro in a Release build.
An early look at Expo Modules 2.0 has the benchmark and covers the API in more depth.
On Android, the Kotlin side shows the same pattern, and this time we also measured against React Native's TurboModules. Across twelve microbenchmarks, Expo Modules 2.0 is faster than Expo Modules 1.0 in every case, from 1.2× for passing an array of 100 numbers to 39.9× for emitting an event with a number. It is also faster than a TurboModule in every case: a call with no arguments takes 112 ns against 2,837 ns, passing an array of 20 objects takes 10.7 µs against 149.8 µs, and emitting an event with an object takes 963 ns against 8,080 ns.
SDK 57 shipped the iOS macros as an experiment. With SDK 58 beta, Expo Modules 2.0 is in beta on both iOS and Android. Documentation is coming during the beta period, and the early look blog post is the best guide until then.
Fewer unnecessary native rebuilds with the new fingerprint default
Bumping a version, or changing files inside node_modules, no longer means a new fingerprint. SDK 58 defaults fingerprint to the balanced preset (#47668). It ignores common cases like updating version in app.json, and hashes native modules by package name and version instead of their files and directories. The hash stays stable without extra config. Learn more about fingerprint presets if you want a different tradeoff.
Experimental: 2× faster cold bundling with a Rust-based transformer
Metro's cache keeps warm bundling fast, but cold bundles, whether a full project or a changed module, spend most of their time in Babel. SDK 58 introduces an experimental replacement: "Noxcturnal", a module transformer written in Rust on top of oxc and exposed to Node.js through napi-rs. In our internal testing, per-module transform time was about 3× faster and end-to-end cold bundling about 2× faster (#48443). On our largest test app, a cold bundle of roughly 5,500 files went from 5.26 seconds with Babel to 2.46 seconds with the new transformer, with 443 files still falling back to Babel.
Try it by setting experiments.noxcturnalTransformWorker in your app config. It only activates when your project has no custom transform worker or Babel plugins and presets, and it skips files that need the Reanimated or Worklets Babel transforms. This is early work: the implementation and the numbers may change before it's stable, and we plan to add configuration options so that more projects, including those with custom Babel transforms, can use it.
Expo Router: stable data loaders and native tabs, improved core
Data loaders, server-side rendering, and middleware are now stable and no longer need experimental flags.
Native tabs, toolbars, and the standard navigation integration are also stable.
Expo Router's navigation core has also been reworked so that navigation state is deterministic and easier to reason about, and it no longer carries most of the forked React Navigation API. Most apps won't notice. If you built a custom navigator or import from expo-router/react-navigation, some APIs have moved or been removed. If one you need is missing, please open an issue and describe what you're trying to do.
Other changes are listed below. We'll add more documentation links soon.
- Navigator migration: JavaScript Tabs, TopTabs, and Drawer now use the same standard-navigation integration as NativeTabs, making their behavior more consistent.
- Loader caching: call setResponseHeaders({ 'Cache-Control': 'private, max-age=60' }) from expo-server inside a loader to let the client cache its response for 60 seconds.
- React transitions and Activity: navigation uses React transitions to keep the current screen visible while the next one loads. Set activityEnabled on a navigator or screen, or wrap part of a screen in NavigationAwareActivity, to hide inactive content while preserving its state and cleaning up its effects.
- Async routes on web by default: the expo-router config plugin now enables asyncRoutes for web automatically. Route files are split into separate JavaScript chunks, which the browser loads when navigating to those routes. Set asyncRoutes: { web: false } to disable this.
- Custom router API: use extendRouter to override parts of a built-in router, or extendRouterActions to add handlers for custom navigation actions.
- Screen error boundaries: set unstable_settings.screenErrorBoundary in a layout or pass to show fallback UI for a screen that throws, while keeping the navigator mounted.
- Optional dependencies: on Android, install expo-symbols for NativeTabs.Trigger.Icon with the md prop and @expo/ui for Stack.Toolbar. These packages are now optional peer dependencies.
Review the migration guide when upgrading, especially if you use custom navigators or import from expo-router/react-navigation.
Connecting to dev servers through proxies and tunnels
If you run your dev server behind a proxy, on a remote machine, or over a tunnel, development builds should now connect to it reliably. Previously, the manifest a development build fetched on startup told it which bundle URL and debugger hostname to use, and those could point at an address the client couldn't reach when the server sat behind a proxy or was discovered over Bonjour. The manifest now uses relative URLs when the client supports them (#47255, #48997).
RCT_METRO_PORT was a compile-time macro frozen at 8081 in prebuilt React Native, so bare apps without expo-dev-client always talked to port 8081, and two such apps running at once answered each other's reload commands. Prebuild now writes the port to the RCTMetroPort key in Info.plist, which the app reads at launch (#48098). Expo CLI port selection is also more consistent, and non-interactive runs roll over to the next free port instead of failing (#47771, #48300).
A faster, more reliable Expo CLI tunnel
Expo CLI has a new tunnel implementation built on @expo/ws-tunnel 2.0 (#46696). It connects faster, holds the connection more reliably, and no longer needs @expo/ngrok. Try it with:
EXPO_UNSTABLE_TUNNEL_V2=1 expo start --tunnelYou'll need to be signed in to your Expo account (expo login) to use it.
The EXPO_UNSTABLE_TUNNEL_V2 flag will be dropped later in the SDK 58 beta and this will become the new default tunnel implementation.
React Native 0.88 (Release Candidate)
SDK 58 beta upgrades React Native from 0.86 to the 0.88 release candidate, so it picks up the changes from both React Native 0.87 and the React Native 0.88 release candidate. Highlights of 0.88 include:
- Swift Package Manager tooling: the opt-in npx react-native spm command and SwiftPM package generation. CocoaPods remains the default and supported path.
- fontVariationSettings on Text: an object syntax for setting variable font axes, which pairs well with the variable font support added to expo-font in this release.
- ArrayBuffer in TurboModules: JavaScript ArrayBuffer values now have native representations on both Android and iOS, with an explicit byte-ownership contract.
- React Native DevTools: experimental performance screenshots, and WebSocket inspection in the Network panel.
Refer to the React Native 0.87 release notes and the React Native 0.88.0-rc.0 release notes for the full picture. We will update this section with a link to the React Native 0.88 blog post when it is published.
PostHog integration
You can now set up PostHog in an Expo app with one command, and every event it captures knows which EAS update it came from. Run eas integrations:posthog:connect and EAS CLI creates or links your PostHog project, installs the SDK and its config plugin, and writes the environment variables to your project and to EAS. PostHog recognizes the eas/update_id, eas/build_id, eas/channel, and eas/runtime_version properties and links them back to expo.dev. This is an EAS CLI feature, so it works with any SDK version. Read the PostHog integration changelog and the Using PostHog guide.
Other notable changes
- expo-camera: added CameraView.scanDocumentAsync for multi-page document scanning on Android and iOS (#47362).
- expo-file-system: added File.digest() for MD5/SHA-1/SHA-256/SHA-384/SHA-512 hashes (#48089), and File.preview() and File.canPreview() for native preview flows.
- expo-audio: added lockscreen controls with playlists (#46020) and WAV/PCM file recording with AudioStream.startFileRecordingAsync (#46771).
- expo-image: added transition.skipOnCacheHit to skip transitions for cached images (#48181), and an svgVariables prop that substitutes values for the CSS custom properties an SVG source refers to with var(), so different parts of one document can be given different colors while the image stays a vector (#48663). Values are not limited to colors. SVG sources that use var() now render with their fallback values even without the prop.
- expo-secure-store: added requireConfirmation on Android for authenticated reads and writes (#48556).
- expo-dev-launcher: added disableFab=1 and disableAutoLaunch=1 URL params to hide the floating action button and prevent the dev menu from opening at launch (#49651).
- expo: URL and URLSearchParams were rewritten with IDNA/TR-46 support (#47813), and TextDecoder was rewritten for speed (#48877).
- expo-sqlite: ships a co-located agent skill that shares best practices with agents. Run npx @expo/agent-cli skills:sync to set it up in your project (#49867).
- expo-font: added support for variable fonts across Android, iOS, and web, so a single font file can provide a family with several weights or styles. This works with useFonts, loadAsync, and the config plugin (#48129, #48621, #48432, #49486, #49487, #49485).
- expo-notifications: on iOS, notification center calls are forwarded to a UNUserNotificationCenterDelegate registered by another library, so expo-notifications and another push library can coexist in the same app (#48313), and notifications can be grouped with threadIdentifier (#49429). On Android, a new delivery: 'alarmClock' option on date and repeating triggers uses AlarmManager.setAlarmClock(), which OEM battery policies don't defer, for time-critical alarms (#49687), and the config plugin gained a largeIcon property (#49481).
- expo-location: we're rewriting expo-location around a location provider abstraction, with a simpler position API, position watchers, background location updates, and new permission options such as requesting temporary full accuracy on iOS (#49849, #49972, #49988). The rewrite will ship as an opt-in preview alongside the existing API, so nothing changes for current expo-location code in this beta. We'll share more once it's ready to try.
- @expo/cli: Android Virtual Device (AVD) and adb management has been rewritten to be more resilient to failures (#49258).
Deprecations
- expo-file-system: File.md5 is deprecated in favor of File.digest() (#48089).
- expo-modules-core: NativeArrayBuffer is deprecated in favor of ArrayBuffer (#47106).
- expo-observe: the AppMetrics export is deprecated in favor of Observe (#48901).
- expo-sqlite: the useLibSQL config plugin property is deprecated and no longer has any effect (#48543).
- @expo/ui: on iOS, backgroundOverlay is deprecated in favor of background (#49621), and the color parameter of border and strokeBorder is deprecated in favor of content (#49838).
Notable breaking changes
- React Native Strict TypeScript API: React Native 0.87 makes the Strict TypeScript API the default. Deep imports from react-native/Libraries/* are now type errors, and some types changed shape, most visibly refs, which now use instance types such as ViewInstance and TextInputInstance. Follow the migration guide, or hand it to an agent with the migrate-to-strict-api skill. To defer the migration, set "customConditions": ["react-native", "react-native-legacy-deep-imports"] in tsconfig.json (keep "react-native", which expo/tsconfig.base already sets). This opt-out is removed after React Native 0.88, so plan to migrate during the SDK 58 cycle.
- React Native API removals: InteractionManager (use requestIdleCallback), the Touchable root export, the NativeMethods types, the Modal animated prop, and the deprecated StatusBar backgroundColor, translucent, and networkActivityIndicatorVisible props are removed. ImageBackground is deprecated in favor of a View with an absolutely positioned Image. See the 0.87 and 0.88.0-rc.0 release notes for the full list.
- iOS scene-based life cycle: the iOS 27 SDK requires the UIScene life cycle, so npx expo prebuild now generates SceneDelegate.swift and a UIApplicationSceneManifest entry in Info.plist, and the UIWindow is created by the scene delegate instead of in didFinishLaunchingWithOptions (#46733, #46734). Expo forwards URL, user activity, Handoff, life cycle, and quick action events to ExpoAppDelegate overrides and subscribers, so config plugins and modules built on those keep working (#49925, #50032). If you manage the ios directory by hand, have a bare React Native app, or override app delegate methods directly, see the migration guide.
- NODE_ENV and environment files: every Expo CLI command now sets NODE_ENV to development or production before loading .env files and your app config, so a dynamic app.config.js and the .env cascade always agree on the mode (#48554, #48741, #48839). Previously, every command kept an inherited NODE_ENV if one was set, and expo config never set one at all, so NODE_ENV=test npx expo start loaded .env.test. An inherited value is now ignored, and that command loads .env.development. Jest still sets NODE_ENV=test in your tests, and @expo/env still resolves .env.test.local, .env.test, and .env there. See the environment variables guide.
- Android app template: R8 is now enabled by default in release builds through android.enableMinifyInReleaseBuilds=true in gradle.properties (#50108). R8 shrinks, optimizes, and obfuscates Java/Kotlin code, which reduces app size and improves startup time. Apps are optimized with the proguard-android-optimize.txt preset. Libraries that rely on reflection may need ProGuard keep rules. To opt out, set android.enableMinifyInReleaseBuilds to false with expo-build-properties.
- expo-router: the navigation core changes make navigation states and route keys deterministic, defer navigation dispatch until after commit, and remove a large portion of the forked react-navigation API surface. @expo/ui and expo-symbols are now optional peer dependencies. The migration guide covers each change, and the expo-router changelog has the full list.
- expo-file-system: File.write() is now async and returns a promise; use File.writeSync() for the previous behavior (#45992).
- expo-sqlite: libSQL support is removed — syncLibSQL() and libSQLOptions are gone (#48543).
- expo-notifications: foreground notifications are now shown by default unless your setNotificationHandler says otherwise, and a slow handler no longer drops the notification (#49072). See Other notable changes for the other expo-notifications changes in this release.
- @expo/fingerprint: the default preset is now balanced (#47668).
- @expo/ui: on iOS, top-aligns its content instead of centering it, so a flex: 1 host matches Android (#47561). HStack, VStack, and GlassEffectContainer now forward an unset spacing to SwiftUI as nil and use the system default spacing; pass spacing={0} to keep the previous layout (#48441). On Android, the style prop is removed from RNHostView; use modifiers instead (#48970).
- expo-localization: on iOS, RTL is no longer force-enabled from the device locale with supportsRTL; layout direction follows I18nManager (#48086).
- expo-media-library: on iOS, Asset.getUri() and AssetInfo.uri now resolve the current Photos version of a video; pass version: AssetUriVersion.ORIGINAL for the previous behavior (#48640).
- @expo/cli: browser-based login is now the default for expo login; use --no-browser or --username / --password for the previous behavior (#46832).
Tool version bumps
- Node.js: Expo tooling now requires Node.js 22.13 or newer on the 22 line, 24.3 or newer on the 24 line, or Node.js 26 and later. Odd-numbered releases such as 23 and 25 are not supported (#47202).
- Android Gradle Plugin: Expo modules tooling is now compatible with AGP 9 (#46766, #46769).
Known regressions
- None reported yet. We'll update this section as we learn more during the beta.
How to try out the beta release
Initialize a new project with SDK 58 beta
# npm npx create-expo-app@latest --template default@next # bun bun create expo-app --template default@next # pnpm pnpm create expo-app --template default@next # yarn yarn create expo-app --template default@nextNote: create-expo-app will install dependencies with the package manager that you are using. For example, with npm when npx is used and yarn when yarn create is used.
Upgrade an existing project
Try using our expo-upgrade skill with Claude Code to upgrade your app to the beta. We appreciate reports for any issues that you encounter so we can further tune it in the coming weeks.
The following instructions explain the manual steps to upgrade your app.
Upgrade all dependencies to match SDK 58:
- npx expo install expo@next --fix
Read the SDK 58 documentation for full API references.
What to test
- Upgrade and test: run npx expo install expo@next --fix, then consult the Native project upgrade helper and report any issues you encounter.
- Build natively: build with EAS Build (the Xcode 27 and SDK 58 images are coming soon, see above), or if you have Xcode and Android Studio installed locally, try prebuilding and running: npx expo prebuild --clean and npm run ios and npm run android. Alternatively, try npx expo run. Any new issues? Please report them.
- Spot a docs gap? Let us know.
How to report issues
- Use the correct issue template: open an issue and fill out the appropriate template, and include a minimal reproducible example.
- Identify the root cause if you can: it's always super helpful and helps expedite a fix.
- Mention you're on the SDK 58 beta: we'll prioritize the issue accordingly.
Thank you for testing out the beta, we appreciate you!
Original source - Sep 9, 2026
- Date parsed from source:Sep 9, 2026
- First seen by Releasebot:Sep 9, 2026
Connect PostHog to your Expo app in one command
Expo adds one-command PostHog integration for React Native apps, linking analytics, session replay, and error tracking with EAS release data. It also brings workflow functions for rollout control, metric checks, and source map uploads to make debugging and release automation easier.
Set up PostHog analytics, session replay, and error tracking, then tag every event with the EAS update it came from.
Adding PostHog to a React Native app used to mean creating an org, creating a project, installing three or four packages depending on the features you wanted, wiring up a config plugin, copying keys between browser tabs, and setting up all the local and remote environments so not only you but your whole team and CI could leverage it. Now it's one command:
- eas integrations:posthog:connect
It creates your PostHog org and project, installs the SDK, adds the config plugin, and writes your keys into .env.local and your EAS environment variables for Production, Preview, and Development. You choose the data region and the features you want. If you are already on PostHog, it opens your browser once to link your existing org and project, then runs the same setup.
What you can learn from it
Product analytics tells you what your users did. This integration tells you which release they were on when it happened, with almost no setup.
Today, a few lines in your app register eas/update_id, eas/channel, and eas/runtime_version as super properties. From then on, every capture() call carries them. Your EAS Workflows speak the same language: pass the same eas/ names to posthog_capture_event, filled from contexts like ${{ app.id }} or job outputs like build_id, and an event from your CI looks exactly like one from a phone.
PostHog knows these names. It shows the Expo logo next to each one and turns the identifiers into links back to expo.dev. Click an eas/update_id in PostHog and you land on that update in your Expo dashboard.
That changes how you debug. With a funnel dropped on Tuesday, you can now break it down by update ID, find the update it started on, and open it. A crash spike, a slow screen, a retention dip after a channel rollout: same move every time. No timestamp matching, no tab juggling.
It also changes what your pipeline can do on its own. EAS Workflows can capture events, mark deploys on your PostHog charts, roll a feature flag forward or back, and hold a job until a live metric clears. Publish an update to 25 percent of users, watch the exception count for 30 minutes, and let the workflow decide whether it goes to everyone or gets pulled.
Rollouts that watch themselves
That last part deserves a closer look, because it changes what release day feels like.
Every EAS Workflow is a chain of jobs, and PostHog now has steps in that chain with native workflow functions!
posthog_flag_rollout sets a feature flag to a percentage.
posthog_wait_for_metric runs a HogQL query on an interval and holds the job until the result clears your threshold, or the timeout fails it.
posthog_wait_for_query is the yes-or-no version: it clears as soon as the query returns true. Put them next to your update or build job and the workflow stops being a fire-and-forget script. It waits, it looks at production, and it picks the next job based on what it sees.Feature flags aren't the only lever. The same pattern works with EAS Update channel rollouts. Send 10 percent of a channel to the new update, watch the error rate, then widen to everyone or revert. The recipe also records how close each rollout came to its threshold as a PostHog event, so after a few weeks you have a chart of your own release health.
From those pieces we built a few more. A kill switch that turns a flag off the moment errors spike, on a schedule, with nobody on call. A nightly error budget check that only speaks up once you've spent the budget. A store submission job that adds an annotation to your PostHog timeline, so every deploy shows on the charts your team already looks at. And posthog_upload_sourcemaps in the build job, so stack traces in PostHog error tracking point at your TypeScript instead of a minified bundle.
Get started today!
Run eas integrations:posthog:connect in a project linked to EAS. Pick a region, pick your features, and let it finish. Then wrap your app in , add the release properties, and make a development build. Fire one test event and open PostHog with eas integrations:posthog:dashboard to watch it land.
A note on Expo Go: product analytics works there. Session replay and crash symbolication need a development build, and release tracking only kicks in once your app is running a real update.
Using PostHog walks through the full setup, and we have over 10 EAS Workflows recipes ready to drop into your .eas/workflows/ or native functions ready to be used within your existing workflow. We are excited to unleash the power of observability combined with automation and what you all will build with it!
Original source Similar to Expo with recent updates:
- Anthropic release notes906 release notes · Latest Oct 20, 2026
- Smokeball release notes147 release notes · Latest Oct 2, 2026
- Cosmolex release notes20 release notes · Latest Jul 30, 2025
- PracticePanther release notes36 release notes · Latest Aug 11, 2026
- Salesforce release notes83 release notes · Latest Oct 1, 2026
- Microsoft release notes1046 release notes · Latest Oct 21, 2026
- Sep 2, 2026
- Date parsed from source:Sep 2, 2026
- First seen by Releasebot:Sep 3, 2026
Login now required for running projects in Expo Go
Expo Go adds support for Expo SDK 57 on iOS and updates its development login flow, requiring users to sign in with the same Expo account in both the CLI and the app to load projects in development mode.
Expo Go has recently been updated in the Apple App Store, and now supports projects running on Expo SDK 57. Expo Go users are now required to be logged in to both the Expo CLI running in your terminal and the Expo Go app in order to run your app in development mode.
If you are not logged in on either the terminal or in the app, when running
npx expo startand scanning a QR code with your camera app, you may see one of the following messages:
The Expo Go app will tell you if you need to login on the terminal, the app, or both.
If you need to login on the terminal, run
npx expo loginand follow the link to login to your account in your web browser.
If you need to login on Expo Go, go to home, tap the avatar icon in the upper right corner and enter your Expo username and password to login.
Once you’re logged in on both sides, try scanning the QR code again (or tap the development server address on the Home tab) and your app should load.
Note that you will need to be logged in to the same account on both the terminal and in Expo Go.
This requirement currently only applies to the latest version of Expo Go for iOS, and will be extended to the Android version in the future. It does not apply to simulator versions. We recommend signing in to your account in Expo Go for Android, this automatically surfaces your running dev servers and allows you to load your published projects. Login is not required for development builds.
Original source - Aug 20, 2026
- Date parsed from source:Aug 20, 2026
- First seen by Releasebot:Aug 21, 2026
EAS Observe is now generally available
Expo moves EAS Observe from public beta to general availability, bringing real-world app performance dashboards for startup, navigation, EAS Update, and more. It includes new retention and plan-based usage limits, with overage billing for Starter plans and above.
EAS Observe helps you understand how your app performs in the real world, with dashboards for app startup, navigation, EAS Update, and more. Today, August 20, 2026, it moves from public beta to general availability. No action is required to continue using Observe.
Every plan includes 90 days of data retention. The Free plan includes 100,000 events per month and access to the main Observe dashboard. Starter plans and above include 500,000 events per month and access to current and future observability dashboards. Starting today, usage beyond the included amount is billed at $5 per 1 million events for Starter plans and above.
You can see the full pricing table for Observe on our pricing page.
If you would like to manage event volume, you can adjust your project’s sample rate. You can also turn off data collection in your project’s settings, in the “Observe data ingestion” section.
You can get started with EAS Observe with our docs.
Questions or feedback about pricing? Let us know at [email protected].
Original source - Aug 13, 2026
- Date parsed from source:Aug 13, 2026
- First seen by Releasebot:Aug 13, 2026
Connect Expo in the Claude desktop app
Expo adds its MCP server to Claude’s connector directory, making it easy to connect once and use across Claude web, Desktop, Mobile, Cowork, and Claude Code. The listing removes setup friction while existing manual setups keep working.
The Expo MCP server is now in Claude's connector directory.
Add it at claude.ai/directory/connectors/expo, sign in with your Expo account once, and it stays connected. Thanks to the Anthropic team for reviewing the submission and getting us listed.
On a Claude Team plan you may see a Request button instead of Connect. That is expected, not an error. It sends the connector to your admins, who can enable it for the whole organization.
What a connector is, and what changes
You could always add the Expo MCP server by hand: a CLI command in your coding agent, or a URL in a config file. That still works, and existing setups keep working. The listing removes the setup step.
A connector is a hosted MCP server that Claude talks to over the network. You authorize it once and Claude can use its tools. A plugin is a bundle that packages skills, sub-agents, and MCP servers into one install. The difference is where each one runs: plugins run in Claude Code, in chat on the web and in the Claude Desktop Chat tab, and in Cowork. Connectors run in all of those plus the Claude mobile apps.
So one listing puts Expo everywhere Claude runs: claude.ai, Claude Desktop, Claude Mobile, Cowork, and Claude Code. Connect once and it is there in whichever one you open.
Prompts to try
Most of the tools never touch your repo. They talk to EAS and the app stores, so they work from a phone as well as a laptop. These work as typed:
- "Start a production iOS build and show me its status."
- "Submit the latest iOS build to TestFlight."
- "Any new TestFlight crashes since yesterday? Show me the stack trace."
- "Show me the latest TestFlight feedback from testers, with screenshots."
- "What are people saying in our recent App Store reviews?"
- "Reply to that 2-star review and apologize for the crash on launch."
- "Show me the latest ANRs from Google Play."
- "Run the deploy workflow and show me the logs."
The review reply tools write in public, so Claude shows you the text before it posts.
Plans and access
MCP usage is included on the Free plan. Paid plans get higher limits and earlier access to new capabilities. Usage counts per billing account, so members of an organization share one allowance.
What still needs your machine
In a coding agent like Claude Code, with an Expo project open, the same connector also searches the Expo docs and installs version-compatible packages.
Screenshots, tap automation, React Native DevTools, and the Expo Router sitemap need a dev server running next to your simulator. Setup for those has not changed. See the MCP docs.
Get started
Connect at claude.ai/directory/connectors/expo, or read the MCP docs for setup in each client. Tell us what you want the connector to do next. Find us in Discord or on X.
Original source - Jul 20, 2026
- Date parsed from source:Jul 20, 2026
- First seen by Releasebot:Jul 24, 2026
EAS Observe moves to general availability on August 20
Expo announces EAS Observe will move from public beta to general availability on August 20, 2026, with 90 days of data retention, updated event limits, and pricing for Starter plans and above. It also expands dashboard access and billing options for observability.
EAS Observe helps you understand how your app performs in the real world, with dashboards for app startup, navigation, EAS Update, and more. On August 20, 2026, it will move from public beta to general availability. Nothing changes today, and no action is required to continue using Observe.
At general availability, every plan will include 90 days of data retention. The Free plan will include 100,000 events per month and access to the main Observe dashboard. Starter plans and above will include 500,000 events per month and access to all current and future observability dashboards. Starting August 20, usage beyond the included amount will be billed at $5 per 1 million events for Starter plans and above.
You can see the full pricing table for Observe on our pricing page.
If you would like to manage event volume, you can adjust your project’s sample rate. You will also be able to disable event ingestion on your account or project before billing begins.
You can get started with EAS Observe with our docs.
Questions or feedback about pricing? Let us know at [email protected].
Original source - Jul 6, 2026
- Date parsed from source:Jul 6, 2026
- First seen by Releasebot:Jul 24, 2026
Sign in with passkeys
Expo adds passkey sign-in for accounts, offering a more secure login method and direct access for users with 2FA enabled.
You can now add passkeys to your Expo account and use them to sign in. They can be managed at expo.dev/settings#sign-in-methods.
Passkeys are a primary authentication factor that is more secure than the combination of a password and OTP. Users who have 2FA enabled can use a passkey to sign in directly, without a second step.
Passkeys are not available to SSO users, as their authentication is managed through their organization's identity provider.
Learn more about passkeys at fidoalliance.org/passkeys.
Original source - Jun 30, 2026
- Date parsed from source:Jun 30, 2026
- First seen by Releasebot:Jul 24, 2026
Expo SDK 57
Expo releases SDK 57 with React Native 0.86, delivering a small, focused upgrade that aims to be easy to adopt and mostly non-breaking. It also adds a few Expo improvements, including dev-client, prebuild, image cache, router, and navigation bar updates.
Today we're announcing the release of Expo SDK 57. This is a small, focused release: it brings React Native 0.86 to Expo. We intend for this to be the easiest Expo SDK upgrade you've ever made. It represents a possible shift towards a new Expo SDK release cadence that could provide you with simple non-breaking upgrades in between more significant releases.
React Native 0.86
SDK 57 upgrades React Native from 0.85 to 0.86. The React version is unchanged from SDK 56 — both SDK 56 and SDK 57 use React 19.2. React Native 0.86 is intended to have no breaking changes from 0.85. To decide whether it's worth upgrading your app, refer to the React Native 0.86 release notes for the full picture.
Highlights include: fixes and improvements to edge-to-edge support on Android, light/dark mode emulation in React Native DevTools, and several rendering, layout, and animation-related fixes.
Exploring a new Expo SDK release cadence
For several years, Expo SDK has seen major releases three times per year. We found that this cadence provided a good balance between stability for app developers and freedom for our team to ship significant new features and improvements. It also helped to reduce thrash in Expo Go.
During the same period, React Native has been releasing six times per year. The React Native team prioritized shipping often in order to incrementally roll out the New Architecture, a new React Native DevTools experience, Hermes V1, and more. Each Expo SDK release would target a single React Native version, and for versions that were not targeted, developers could use canary releases if needed. However, now that these massive changes to React Native have shipped, the focus has shifted towards stability.
The new release model that React Native is moving towards will aim to provide a release with "no user-facing breaking changes" approximately every second release. The recently released 0.86 is the second of these non-breaking releases. At Expo, the fact that these releases are intended to be non-breaking has prompted us to revisit our release cadence. If we can provide these releases to developers almost immediately, as optional upgrades, with little effort required for the app developer beyond running npx expo install expo@latest --fix, then we think we should do it. So, we are exploring that approach with SDK 57.
Why not include React Native 0.86 in SDK 56 if it is non-breaking?
This is a good question! We considered bumping from 0.85 to 0.86 in SDK 56, and ultimately decided that the set of changes between the versions was too significant for an app developer to pull in with a routine npx expo install --fix. There are 601 commits touching 1,552 files between 0.85.0 and 0.86.0, and we believe that the decision to pull those into your app should be intentional. Even though these commits are intended to not cause breaking changes, we think it's best to err on the side of being conservative.
Additionally, moving this bump to a new SDK version allows us on the Expo team to roll out small changes that wouldn't be appropriate to ship to an existing stable release, but that we think are genuinely useful for users. The following list includes some of those changes that are worth calling out.
Does this new cadence impact the Expo SDK maintenance window?
SDK releases will continue to have a lifetime of approximately one year. We may revisit the details of this policy in the future. What this means today is that Expo SDK 54 (September 2025) will receive critical fixes until the next SDK release (September or October 2026).
Will there be a new Expo Go version on the App Store and Play Store?
We'd like to release a new version for SDK 57, but we're still waiting on approval. Expo Go for SDK 57 is available with eas go for iOS devices, and through Expo CLI for Android devices/emulators and iOS simulators (learn more).
Other highlights
While SDK 57 is primarily about the React Native 0.86 upgrade, a few other improvements landed alongside it:
- expo-dev-client: the iOS launcher includes a new setting to choose between auto-launching your most recent project or showing the launcher (#47131), allowing you to override the configuration set with the config plugin.
- expo prebuild: now clears and regenerates the native android and ios directories by default; pass --no-clean to apply changes to the existing folders instead (#47209).
- expo-image: added writeToCacheAsync and readFromCacheAsync to seed and read the image cache by cache key (#46620).
- expo-router: Stack.Toolbar.Badge is now supported in header left and right placements and on toolbar menu icons on Android (#46537, #47276).
- expo-navigation-bar: setStyle and setHidden now apply to React Native windows on Android (#46491).
- Bump animation and gesture libraries: SDK 57 bundles newer versions of react-native-reanimated (4.3 to 4.5), react-native-worklets (0.8 to 0.10), and react-native-gesture-handler (2.31 to 2.32).
Known regressions
- Increased memory usage with Hermes V1 and react-native-reanimated: importing react-native-reanimated can increase your app's memory usage by 25–30%, even if you don't actively use the library, due to a change in Hermes that shipped with React Native 0.85 (software-mansion/react-native-reanimated#9650). This also impacts SDK 56. As a workaround, enable worklets bundle mode. A fix is coming in Hermes V1 soon.
Upgrading your app
You should expect this to be a straightforward upgrade from SDK 56 / React Native 0.85, thanks to the absence of breaking changes in React Native 0.86.
Try using our upgrade skills (installation instructions) with Claude Code, or a similar tool of your choice, to upgrade your app.
Here's how to upgrade your app to Expo SDK 57 from 56:
- Upgrade all dependencies to match SDK 57:
npx expo install expo@^57.0.0 --fix - Check for any possible known issues with Expo Doctor:
npx expo-doctor@latest - Make sure to check the changelog for all other breaking changes!
- If you use Continuous Native Generation:
- Delete the android and ios directories if you generated them for a previous SDK version in your local project directory. They'll be re-generated next time you run a build, either with npx expo run:ios, npx expo prebuild, or with EAS Build.
- If you don't use Continuous Native Generation:
- Run npx pod-install if you have an ios directory.
- Apply any relevant changes from the Native project upgrade helper.
- Optionally, you could consider adopting prebuild for easier upgrades in the future.
- If you use development builds with expo-dev-client: Create a new development build after upgrading.
- If you use Expo Go: consider migrating to development builds. Expo Go is not recommended as a development environment for production apps.
- Having trouble? Refer to the Troubleshooting your SDK upgrade guide.
- Questions? Join our weekly office hours on Wednesdays at 12:00PM Pacific on Discord.
- Jun 24, 2026
- Date parsed from source:Jun 24, 2026
- First seen by Releasebot:Jul 24, 2026
Maestro testing: insights, clearer results, and faster retries
Expo adds a new Maestro insights dashboard for tracking E2E test runs over time, spotting flaky flows and failure patterns, and reviewing recent runs in the Insights tab. It also brings a clearer Test Results summary and retries that re-run only failed flows.
Introducing a new insights dashboard
Introducing a new insights dashboard, showing you how every Maestro end-to-end test run performed over time, across your whole team. Identify flakey tests, see when regressions were introduced, and stop scrolling through endless logs.
Your end-to-end tests pass, until they don't. When a Maestro end-to-end (E2E) test fails, acting on it usually means digging through logs to find out what broke, re-running your whole suite to retry one flaky test, and guessing whether things are getting better over time.
Maestro insights collects and visualizes how your Maestro tests perform over time, right in your project's Insights tab. It surfaces:
- Trends: Maestro runs and pass rate across all your flows over time
- Flaky flows identification: flows that pass only after a retry, so you can find and fix the unreliable ones
- Failure patterns: failures grouped by error message, surfacing common causes behind failures
- Filter by test: open a specific test flow to see its recent runs, durations, and error patterns
With our insights, you can also filter by workflow, Git branch, tag, or status, and sort the flow list by runs, failures, flake rate, or P90 duration to find issues fast.
A clearer view of every run
Every Maestro job now opens with a Test Results summary that lists each flow along with its status (passed, failed, or flaky) and duration. Failed and flaky flows also surface their error messages at the top of the page, so you can immediately see what went wrong without digging through logs. Open the screenshot captured at the moment of failure or jump directly to the failure timestamp in the recording to quickly understand what happened.
Together with improved flaky test detection, these updates make it easier to identify issues, understand failures, and take action faster.
Retries that re-run only failed flows
When a Maestro job retries, it now re-runs only the flows that failed on the previous attempt instead of your whole suite. You’ll get faster feedback and fewer wasted CI minutes. This is the default behavior (retry_failed_only); to re-run every flow on each retry instead, set retry_failed_only: false. See the maestro job reference for details.
Built on JUnit output
Maestro insights, the Test Results summary, and failed-flow-only retries all build on the JUnit report the Maestro job produces by default (output_format: junit). If you've overridden output_format to another value, switch back to junit to use these features.
Get started
Maestro insights is currently available to Production (up to 30 days of history) and Enterprise plan (update to 1 year of history) subscribers. To see your project’s Maestro insights, open the Maestro tab in your project's Insights through the left sidebar. New to E2E testing on EAS? Follow our guide to running Maestro tests in EAS Workflows.
Original source - Jun 15, 2026
- Date parsed from source:Jun 15, 2026
- First seen by Releasebot:Jul 24, 2026
Automate iOS device registration for internal builds in EAS Workflows
Expo adds automated iOS internal distribution workflows with ad hoc provisioning profile refresh in the CLI and EAS Workflows, plus device registration jobs that let teams enroll, approve, refresh profiles, and build installs for newly registered devices.
There are several ways to distribute iOS apps to your team: for devices, you can use TestFlight, ad hoc provisioning, or enterprise provisioning, and for simulators you can share a direct link to the build that can be installed manually or through Orbit. EAS makes it easy to use all of these approaches, so you can do what works best for any particular build or process. When distributing to devices, most developers will use some combination of TestFlight and EAS internal distribution with ad hoc provisioning.
With ad hoc provisioning, only devices listed in the profile at build time can install the build. So you need to register your device with EAS (which handles registering it with Apple), regenerate the profile, and then rebuild the app. This process has been difficult to automate in the past because the only way to refresh the profile was for a developer to manually run eas build or eas credentials. In other words, there was no way to refresh an ad hoc profile with --non-interactive or in EAS Workflows, so automated internal builds could succeed, but they would not install on a newly enrolled device.
We've shipped three updates to close that gap in automation:
- Ad hoc provisioning profile refresh on the CLI: --refresh-ad-hoc-provisioning-profile on eas build updates the ad hoc provisioning profile from Apple before a non-interactive build.
- Ad hoc provisioning profile refresh in workflows: refresh_ad_hoc_provisioning_profile: true on type: build jobs passes the same behavior through to the build worker.
- Device registration in workflows: the apple-device-registration-request job enrolls a physical device (QR code plus approval), then exposes its details to downstream jobs.
Together they support an automated loop: register and approve a device, refresh the profile so its UDID is included, then build an internal .ipa that installs on that device.
Refresh ad hoc provisioning profiles in CI
EAS CLI 19.1.0 added --refresh-ad-hoc-provisioning-profile. Use it with --non-interactive on an internal iOS build that uses EAS-managed credentials. Before gathering build credentials, EAS authenticates with your App Store Connect API key, reads devices registered on EAS for your Apple team, and creates or updates the ad hoc provisioning profile. The refreshed profile details are stored in EAS credentials and the build continues.
Example:
eas build --platform ios --profile preview --non-interactive --refresh-ad-hoc-provisioning-profileLearn more about automating internal distribution on CI.
Refresh profiles in EAS Workflows
Workflows type: build jobs accept refresh_ad_hoc_provisioning_profile: true in params, the workflow equivalent of the CLI flag. EAS validates the job (iOS platform, internal profile, remote credentials) and passes the setting through to the build worker, which refreshes the profile before the build starts.
Example:
jobs: build_ios_internal: type: build params: platform: ios profile: preview refresh_ad_hoc_provisioning_profile: trueRequest device registration in a workflow
The apple-device-registration-request job pauses the workflow until a developer enrolls and approves their physical iOS device. This is useful for ensuring a device is registered before downstream jobs run.
When the job runs:
- The workflow run enters the "action required" state and shows a QR code in the dashboard.
- A team member scans the code or opens the link on their iPhone or iPad and installs the registration profile.
- A team member approves or rejects the enrollment on the workflow run page. (Enrollment alone does not advance the workflow; explicit approval is required for security.)
On approval, the job exposes outputs you can use downstream, including identifier (UDID), model, and software_version — useful in a downstream Slack job, for example. If your Expo account has multiple Apple teams, set apple_team_identifier in params; with exactly one team, it is optional.
Example:
jobs: register_device: type: apple-device-registration-request params: apple_team_identifier: ABCDE12345End-to-end: register, approve, build
Together, device registration and profile refresh close the loop for internal iOS distribution in automation: enroll a device in the workflow, approve it, then build with profile refresh so the new UDID is on the provisioning profile.
Example:
Original sourcename: Register device and build iOS internal jobs: register_device: type: apple-device-registration-request build_ios: needs: [register_device] type: build params: platform: ios profile: preview refresh_ad_hoc_provisioning_profile: true - May 26, 2026
- Date parsed from source:May 26, 2026
- First seen by Releasebot:Jul 24, 2026
The Expo MCP Server is now available on the Free plan
Expo adds the Expo MCP Server to the Free plan, bringing AI coding assistant access to Expo docs and tools for every Expo account. The update includes monthly Free-plan MCP usage and expands support for debugging builds, checking logs, and verifying app behavior locally.
What you can do with Expo MCP
Connect your AI coding assistant to your Expo project from any Expo plan.
The Expo MCP Server is now available on the Free plan, with monthly MCP usage included for Free accounts. When we first launched the Expo MCP Server, it was available only on paid plans. Now anyone with an Expo account can connect an AI coding assistant to Expo docs and tools.
MCP (Model Context Protocol) is an open standard that lets AI assistants connect to external tools and project context. We introduced the Expo MCP Server in Become an AI-native developer with the Expo MCP Server; this update makes that workflow available to anyone with an Expo account.
Developers are already using Expo MCP for a few common workflows:
- Finding the right Expo answer faster. Your assistant can pull in official Expo documentation and SDK guidance while you are editing code.
- Debugging builds and workflows. It can inspect EAS build status, workflow runs, logs, failures, and related TestFlight crashes or feedback.
- Verifying app behavior locally. With a local dev server and simulator or emulator, it can take screenshots, tap through flows, inspect views, and collect logs.
Included Free-plan usage
Free accounts include monthly MCP usage intended to cover individual development, evaluation, prototypes, and occasional Expo-specific assistant help.
Usage is counted at the billing account level. If your account belongs to an organization, all members share the same included monthly usage. If the account reaches its monthly limit, MCP requests will fail with an error until usage is available again.
For heavier MCP usage, paid plans include higher usage limits and may include access to newer MCP capabilities before they are broadly available.
Get started and feedback
Follow the MCP docs to connect your AI coding assistant to Expo. MCP gives your agent access to Expo tools and project context; Expo Skills give it Expo-specific instructions for building, deploying, and debugging apps.
We'd like to hear what you want MCP and Skills to help with next. Checking whether a release is ready? Understanding update rollout health? Turning build, workflow, or TestFlight signals into concrete fixes? Find us in Discord or on X.
Original source - May 21, 2026
- Date parsed from source:May 21, 2026
- First seen by Releasebot:Jul 24, 2026
Expo SDK 56
Expo releases SDK 56 with stable Expo UI, faster native builds, upgraded React Native and React, richer file system and router APIs, more capable modules tooling, and broader performance gains across Expo CLI, EAS Build, and Expo Go.
Today we're announcing the release of Expo SDK 56. SDK 56 includes React Native 0.85 and React 19.2. Thank you to everyone who helped with beta testing.
Expo UI is now ready for production
As of SDK 56, the Jetpack Compose (Android) and SwiftUI (iOS) APIs in Expo UI are stable. We've added Expo UI to the default create-expo-app template, so new Expo apps can use a rich set of native UI primitives right out of the box, and Expo UI is now available in Expo Go.
This milestone release builds on three SDK cycles of iteration across SDK 53, 54, and 55. Thank you to everyone on the Expo team and in the community who helped test, audit, and refine the APIs from the original SwiftUI prototype to the Jetpack Compose implementation.
SDK 56 focuses on three core pieces of Expo UI: a new universal components API for shared interfaces, stable native APIs, and drop-in replacements for popular React Native community libraries.
Universal components
Expo UI now includes universal components that work across Android, iOS, and web. Unlike the Android and iOS APIs, the web APIs are still experimental and likely to change.
The universal components are backed by @expo/ui/jetpack-compose on Android, @expo/ui/swift-ui on iOS, and react-dom or react-native-web on web. You can now build more cross-platform UI with Expo UI without splitting files into .android.tsx and .ios.tsx.
Universal components include layout primitives, text, inputs, controls, and sheets such as Host, Row, Column, ScrollView, Text, TextInput, Button, Switch, Slider, Checkbox, and BottomSheet.
Stable native APIs
Expo UI's SwiftUI and Jetpack Compose APIs are now stable after several rounds of breaking changes. These changes align Expo UI more closely with the underlying frameworks, so developers and coding agents can lean on native platform documentation and examples directly when writing Expo UI code.
- Extend Expo UI with custom views and modifiers: you can now extend Expo UI with your own SwiftUI and Jetpack Compose views and modifiers. Expo UI manages layout synchronization, props, and events for you. See the guides for examples: SwiftUI guide and Compose guide.
- Material 3 Dynamic Colors and the Material Symbols catalog: the new useMaterialColors hook hands you Material 3 Dynamic Colors that follow the system theme, and the Icon component pairs with @expo/material-symbols to bring the full Material Symbols catalog within import reach.
- react-native-worklets integration and native state: Expo UI now integrates with react-native-worklets and native state primitives from the underlying UI frameworks: ObservableObject on SwiftUI and MutableState on Jetpack Compose. The new useNativeState hook lets JavaScript control that native state directly, which is useful for native state-driven animations and form controls.
- Synchronous worklet callbacks: a new WorkletCallback shared object allows synchronous UI worklet callbacks to be passed as props to Expo UI views on both platforms. TextField on iOS and Compose can now use native state for value, and onValueChange accepts WorkletCallback, enabling synchronous, flicker-free controlled text inputs.
- Components, modifiers, and API changes: SDK 56 lands the bulk of the stabilization work since SDK 55. See the @expo/ui CHANGELOG for the full list.
Drop-in replacements for community components
Expo UI is focused on native primitives, and some of those primitives overlap with popular community libraries. To make migration easier and reduce library fragmentation, SDK 56 introduces drop-in replacements for several common community components.
For example, you can migrate from:
import DateTimePicker from '@react-native-community/datetimepicker';to:
import DateTimePicker from '@expo/ui/community/datetime-picker';Drop-in replacements are available for @gorhom/bottom-sheet, @react-native-community/datetimepicker, @react-native-masked-view/masked-view, @react-native-menu/menu, react-native-pager-view, @react-native-picker/picker, @react-native-segmented-control/segmented-control, and @react-native-community/slider APIs. Most migrations only require changing the import, though some props may be unsupported or differ because Expo UI is backed by SwiftUI and Jetpack Compose rather than UIKit and Android Views.
Faster native builds
Precompiled Expo packages on iOS
SDK 56 ships prebuilt XCFrameworks for our most complex Expo modules on iOS, to speed up your iOS builds. In our measurements, this cuts median clean iOS build times by around 1 minute (~16%) — both locally and on EAS Build. This is enabled by default both locally and on EAS Build — no configuration required. To opt out, set the EXPO_USE_PRECOMPILED_MODULES environment variable to 0 (for local builds), and also as an EAS environment variable (for EAS Build).
Precompiled headers for Android codegen (experimental)
A new opt-in android.usePrecompiledHeaders option in expo-build-properties applies CMake precompiled headers to the C++ codegen output for every autolinked native module, dramatically cutting CMake compile times on Android. In our benchmarks, the :app:buildCMakeDebug task dropped from 17m 10s to 6m 06s — a 2.81x speedup. In a default new project, builds are about 1.3x faster. Results will vary by project, but the larger your autolinked module graph, the bigger the win.
Expo Modules: easier to write, faster to run
Inline modules
Starting with SDK 56, you can now define Expo modules directly within your project structure, alongside your JavaScript and TypeScript code. We call these inline modules, and they make experimenting with native code easier than ever.
After setting up your app to use inline modules, you can open Kotlin and Swift files and write your Expo modules with no additional setup. During prebuild, the iOS Xcode project is updated and the necessary options are set in the Android project, which lets us add inline modules to the build and autolink them automatically.
With the newly released type generation tools, which offer a few CLI commands tailored towards inline modules, you will have an even smoother experience. You can just create a Swift inline module and a CLI watcher will automatically generate a TypeScript interface for it right beside the Swift file. The TypeScript interface is separated into a generated and stable part, so that you have control over your stable TS interface and leave the generated part to be regenerated on any changes. If you want more control you can always generate these files manually.
You can develop inline modules from Android Studio, Xcode, or any other IDE as they are part of your project structure.
Check out the inline modules reference and the tutorial for more information!
Type generation tools
In SDK 56 we introduce a powerful new tool for developing Expo Modules. The new expo-type-information package exports functions that parse and retrieve type information from a Swift Expo module and ones that generate TypeScript interface from the retrieved information.
It also includes a CLI with the following key commands:
- module-interface: takes a Swift Expo module (accepting multiple file paths or a path to the module root) and generates multiple TypeScript files based on our standard interface scheme: [ModuleName]Types.ts (contains all type declarations), [ModuleName]Module.ts (contains the module class), [ModuleName]View.tsx (exports the default view component(s) with typed props), index.ts (re-exports the module alongside every defined type and view).
- inline-modules-interface: generates a pair of TypeScript files (generated, stable) for each Swift inline module in a project.
- short-module-interface: works similarly to inline-modules-interface, but targets a specific Swift module instead of all inline modules in the project.
All of these commands can be run in a watch mode to automatically regenerate the TypeScript interfaces.
Learn more in the expo-type-information reference and tutorial.
Revamped create-expo-module
In SDK 56, create-expo-module has been revamped for improved stability and a richer feature-set.
- New create-expo-module skill: helps agents create Expo modules — coming soon.
- New addPlatformSupport subcommand: adds support for additional platforms in an existing module — for example, adding Android support to an iOS-only module. The command detects the features currently used in your module and scaffolds the native files for you.
- Modular template: when creating a module you can pick which features get scaffolded and which platforms it targets.
- Non-interactive mode support: field defaults have been improved and some fields are no longer required; in non-interactive mode, create-expo-module logs the defaults that were used.
- No barrel file by default: local modules no longer use index.ts; pass --barrel to opt in.
- Windows support: create-expo-module now works well on Windows.
Runtime performance improvements in expo-modules-core
Kotlin compiler plugin — A new Kotlin compiler plugin replaces reflection with build-time code generation for Expo Modules on Android. In our benchmarks, we're seeing roughly 40% faster cold starts and 33% faster first render, with no app-side changes required. By collecting module metadata at compile time rather than runtime, we eliminate the reflection-based function-type-to-converter mapping that has historically been a major speed bump for Expo Modules on Android. Results will vary by project, but this is only the beginning — this compiler-driven approach lets us optimize function invocation directly, starting with a noticeable speed boost for Record conversion in SDK 56.
New JSI layer for iOS native modules — Until now, calling into a native module from JavaScript on iOS meant crossing three language boundaries: Swift, Objective-C++, and C++. In SDK 56 we removed the Objective-C++ middle layer entirely by adopting Swift/C++ interop to talk to JSI directly. Fewer hops means less call overhead, and in our benchmarks we're seeing significant performance improvements across native module calls. The codebase is also significantly easier to work with now that it is Swift all the way down. We'll cover the architecture, benchmarks, and what this enables in an in-depth blog post.
React Native 0.85 and React 19.2
Expo SDK 55 included React Native 0.83, so be sure to refer to the full release notes for 0.84 and 0.85 for the complete picture. A few highlights include:
- Hermes v1 by default: Hermes v1 is now the default JavaScript engine, bringing faster startup times, improved runtime performance, and reduced memory usage. You can opt out with the useHermesV1 configuration in expo-build-properties.
- New animation backend: React Native 0.85 introduces a new animation backend designed to better align with the New Architecture, improving consistency and performance of animations across platforms.
- HTTPS dev server: the Metro dev server now supports HTTPS via TLS configuration, enabling secure local development environments and compatibility with APIs that require secure origins.
- Node.js minimum bump: React Native 0.85 drops support for Node.js versions before v20.19.4.
Hermes bytecode diffing is now enabled by default
In SDK 55 we introduced opt-in Hermes bytecode diffing for expo-updates and EAS Update: instead of downloading a full bundle on every update, the client downloads a binary patch against the previously installed bytecode. In the 24 hours before this post went out, EAS Update served diffed Hermes bundles that were on average 58% smaller than the full bundle they replaced.
Diffing is on by default in SDK 56. To opt out, set "enableBsdiffPatchSupport": false in the updates block of app.json.
We're also working on extending bytecode diffing to patch against the embedded bundle shipped in your native build, not just against the previously installed update. This will give the first update after a fresh install the same size savings that subsequent updates already see. We're planning to ship this as an opt-in feature in an SDK 56 patch release in the coming months.
More capable expo-file-system
SDK 56 fills several parity gaps in the new expo-file-system API that became the default in SDK 54.
File.downloadFileAsync() now reports progress and supports AbortSignal, and copy/move operations accept an overwrite option.
The new API also adds task-based upload and download APIs: file.createUploadTask() and File.createDownloadTask(). These bring back support for long-running transfers from the legacy file-system module, including upload progress, cancellation, and resumable downloads. For simpler uploads, File.upload() provides a convenience wrapper when you do not need to manage an upload task directly.
File picking is more capable now too: File.pickFileAsync() supports selecting multiple files and multiple MIME types, bringing it closer to expo-document-picker feature parity. We also fixed several correctness and reliability issues, including large-file md5 hashing memory usage, Android SAF copy/move support, and totalDiskSpace reporting on iOS.
We've also added experimental file-system event watching with File.watch() and Directory.watch(), which will let apps subscribe to file and directory changes without polling.
Status bar and navigation bar APIs are now consistent
Both expo-status-bar and expo-navigation-bar now expose a React component with the same prop surface, where multiple instances merge in mount order. To make that possible, we added a new component.
We also added a config plugin for expo-status-bar, and both packages' plugin options now align.
New Calendar, Contacts, and MediaLibrary APIs are now stable
With the release of Expo SDK 56, the next versions of the expo-calendar, expo-media-library, and expo-contacts libraries are officially promoted to stable.
The updated APIs have been redesigned with an object-oriented approach. Items like media assets or individual contacts are now represented as classes, which unlocks new features and makes them much easier to work with. Key improvements include granular data fetching (instead of loading entire, heavy objects at once, you can now fetch the specific properties you need) and cleaner querying and filtering using the Builder pattern.
For more technical details and usage examples on the new MediaLibrary and Contacts APIs, check out the blog post.
Widgets for iOS promoted to stable
After introducing an alpha version of Expo Widgets for iOS in SDK 55, we gathered feedback and made many fixes and improvements, and the library is now stable. In SDK 56, Widgets and Live Activities have full access to the environment and no longer need to be pre-rendered. We also improved timeline management, error handling, the config plugin, and the render timeline.
AI-friendly project scaffolding
- Agent-ready scaffolding: new projects include AGENTS.md, CLAUDE.md, and .claude/settings.json with Expo-specific guidance.
- Official Expo Skills for AI agents: install in Claude Code with /plugin marketplace add expo/skills followed by /plugin install expo. For Codex, Cursor, or any other agent, run npx skills add expo/skills. See the docs for per-tool setup details.
Convex integration
EAS now provisions and links Convex backends for you. Run eas integrations:convex:connect in your project and we'll install convex, create (or reuse) a Convex team linked to your EAS account, set up a project with a dev deployment, and write CONVEX_DEPLOY_KEY and EXPO_PUBLIC_CONVEX_URL to your .env.local. We also create EXPO_PUBLIC_CONVEX_URL as an EAS environment variable across Production, Preview, and Development so EAS Build picks it up automatically.
Expo CLI
SDK 56 ships the first wave of performance improvements across the whole bundling and run pipeline, with more landing in future releases.
- Faster CLI: Various performance metrics of the Expo CLI have been improved in SDK 56.
- On-demand Filesystem: eliminates watchFolders as a load-bearing configuration option. Enabled by default; disable it by adding experiment.onDemandFilesystem: false to your app.json.
- Native Node.js watcher by default: rather than Watchman, we now use a native Node.js watcher and crawler by default. You can switch back to Watchman with resolver.useWatchman in a Metro config, but it's no longer recommended.
- TypeScript 6 support and TypeScript 7 readiness: we replaced our TypeScript resolution to support TS 6 and prepare for TS 7. This resolves some monorepo bugs with tsconfig.json's paths config.
- import.meta support: now enabled automatically.
- Hermes v1 transforms: fewer bundler transforms are enabled for Hermes, which reduces bundling times overall.
With the On-demand Filesystem, you can also now try Expo with global virtual stores (such as in Bun and pnpm), which deduplicates installed Node modules across projects (saving ~300 MB per duplicate Expo install) and speeds up installs for agents working across multiple Git worktrees.
Type-safe config plugins
Every Expo package that ships a config plugin now exports it with full TypeScript types. Import the plugin from expo-/plugin into your app.config.ts to get autocomplete, JSDoc, and deprecation hints for plugin options without leaving your editor.
Additionally, config plugins are now loaded with the same module loader that configs themselves use. This means you'll now also be able to reference local .ts files in your plugins list, or write config plugins with .mjs or .cjs extensions.
Expo Router
Expo goes way back with React Navigation: @brentvatne led the project for the 1.0 and 2.0 releases, working together with @ericvicenti and @satya164, and we helped to grow it from an idea, to a conceptual merging of React Native's old NavigationExperimental and ex-navigation, to the standard navigation library in the React Native ecosystem (now one of the standards, alongside Expo Router).
Today, React Navigation is in Satya's great hands, and our focus in the navigation space has shifted towards Expo Router. We spoke with Satya and agreed that the best path forward for both projects was for Expo Router to fork the parts of React Navigation that it builds around. You can, of course, continue to use React Navigation in your Expo projects if you find that you prefer it (try it out: npx create-expo-app@latest --template react-navigation/template). Both libraries build upon react-native-screens and have different takes on the developer experience, with Expo Router preferring file system-based routing. We expect that each library will continue to push the other forward in the future, and that the best ideas will continue to flow between them.
Now that expo-router no longer depends on react-navigation, most code imported directly from @react-navigation/* packages will no longer work out of the box alongside expo-router.
Run the codemod to handle most of the migration automatically (replace [your-source-directory] with your source folder, e.g. src or app):
npx expo-codemod sdk-56-expo-router-react-navigation-replace [your-source-directory]See the migration guide for full details, including manual migration steps.
New features
- On Android, we've added experimental support for a toolbar. You can try it using the same API available on iOS: Stack.Toolbar.
- In collaboration with react-native-screens, we've also introduced experimental support for a new version of the native stack (Stack v5), including initial support for Material-style headers and predictive back gesture.
- For Expo on the Web, we now support streaming SSR when using the unstable_useServerRendering flag. As part of this change, we've also introduced a new generateMetadata function for retrieving and setting metadata on initial page load. The existing component can still be used for updating metadata after hydration.
- We've also added two new helpers for data loaders: createStaticLoader and createServerLoader, which narrow the callback signature for each rendering mode. createStaticLoader receives only route params (no request), while createServerLoader always passes a request and throws an actionable error if mistakenly used during static generation.
- We've also added the ability to customize the default fallbacks in a _layout route, giving you more control over loading states across your app. Following the same convention as ErrorBoundary, you can export a SuspenseFallback that receives route parameters, making it easy to show loading UI.
Brownfield: more flexibility for embedded Expo apps
SDK 56 builds on the brownfield foundation we shipped in SDK 55, with three meaningful additions for teams embedding Expo into existing native apps.
- Multiple isolated apps in one host. A new experimental option lets one host app contain multiple inner expo-brownfield apps. Opt in by setting multipleFrameworks: true on the iOS plugin config, and each framework gets a unique Swift module name plus an auto-applied ObjC symbol prefix across its entire pod dependency graph, so two brownfield apps can ship side by side without colliding.
- Custom Turbo Modules from the host app. Host apps can now register their own turbo module classes with the inner Expo app's React Native runtime, by passing a turboModuleClasses dictionary into ReactNativeHostManager.initialize. This makes it much easier to expose host-app capabilities (auth, app-specific SDKs, native UI controllers) to JavaScript without modifying the inner app's bundle.
- iOS prebuilds by default. expo-brownfield now uses prebuilt React Native frameworks on iOS out of the box, which substantially cuts brownfield build times. If you need to opt back into building React Native from source, use the new buildReactNativeFromSource plugin option.
Expo Application Services (EAS)
Build time statistics for xcodebuild and Gradle
EAS Build now surfaces per-step timing for xcodebuild and Gradle, so you can see exactly where your native build time is spent and decide what to optimize first.
Prebuilt artifacts for major community libraries
Building on the precompiled Expo packages work in SDK 56, EAS Build now precompiles some of the most commonly used community libraries in the React Native ecosystem too — like react-native-reanimated and react-native-screens. In our measurements, this cuts median iOS clean build times on EAS Build by another 1 minute (20%) on top of the Expo-modules precompile, with bigger savings for apps that use more of these libraries.
Coming soon: EAS Observe
We're working on EAS Observe, a production performance monitoring service for Expo apps that tracks real-world metrics on your users' devices. Compare metrics across releases to catch regressions early, then investigate detailed session data (on your own, or hand it off to an LLM) when something looks off.
Other notable changes
- expo-audio: new useAudioStream hook for real-time microphone buffer access. Live-stream improvements: isLiveStream lock-screen option on iOS, playsInSilentMode on Android, and isLive / currentOffsetFromLive / error fields on AudioStatus.
- expo-haptics: web haptics on Safari.
- expo-asset: GLB model assets for 3D / AR work.
- expo-sqlite: native ArrayBuffer for blob columns, statement bind params, and session changesets — replacing the legacy JavaScriptArrayBuffer.
- expo-dev-launcher: error-screen "Copy" button, NDS service discovery on Android, Android edge-to-edge, and plugin options for defaultLaunchURL, skipOnboarding, and showMenuAtLaunch.
- expo-doctor: a new check warns when expo-router and react-navigation are both installed — a likely unintended pairing now that expo-router no longer sits on top of react-navigation.
- expo/fetch: brotli, gzip, and zstd response decompression on Android, and AbortSignal.timeout / AbortSignal.any support for WinterTC-compatible fetch behavior.
Deprecations
- @expo/vector-icons will be replaced by @react-native-vector-icons/*: the new scoped packages (one per icon set) are distinct from the older umbrella react-native-vector-icons package that @expo/vector-icons originally replaced. Migrate today by running npx @react-native-vector-icons/codemod.
- Original expo-calendar, expo-contacts, and expo-media-library APIs: superseded by the redesigned versions now promoted to stable — the original APIs are deprecated.
Notable breaking changes
- expo/fetch as globalThis.fetch: expo/fetch is now installed as the default implementation of globalThis.fetch, providing a WinterTC-compliant API and improved performance. Manual imports are no longer required. To opt out, set EXPO_PUBLIC_USE_RN_FETCH=1 in your .env file.
- Async copy() and move() in expo-file-system: these methods on File and Directory are now asynchronous and return a Promise. Use copySync() and moveSync() for synchronous behavior.
- @expo/dom-webview as the default WebView for DOM components: you no longer need the react-native-webview dependency to use DOM components. You can still opt out and continue using react-native-webview if needed.
- Related to the planned deprecation of @expo/vector-icons, the expo package no longer depends on @expo/vector-icons. If you wish to continue using @expo/vector-icons, you need to explicitly add it to your project's dependencies in package.json.
Tool version bumps
- Minimum Xcode bumped to 26.4.
- Minimum iOS / tvOS bumped to 16.4, macOS to 13.4. Up from iOS 15.1 (last bumped August 2024). Drops support for iPhone 7/7+, iPhone 6s/6s+, iPhone SE (1st gen), iPad mini 4, and iPad Air 2.
- TypeScript bumped to 6.0.3 — included in new project templates and pulled in for existing projects via npx expo install --fix. To opt out, add typescript to the expo.install.exclude field in your package.json.
Expo Go
Reminder: The Expo Go app is our tool for getting started quickly, it's an educational tool to help you learn to build on mobile. If you are past that stage and want to build and ship an app, we encourage you to migrate your project to using a development build.
Expo Go for SDK 56 is not available on the Apple App Store or Google Play Store. We do not have a timeline for when they will be, and we'll update this post when we have more news to share.
- You can install Expo Go for SDK 56 from Expo CLI directly on Android devices.
- For iOS, you can use the TestFlight External Beta or the eas go command to create an Expo Go build for SDK 56 and upload it to your own TestFlight team.
Known regressions
- Increased memory usage with Hermes V1 and react-native-reanimated: importing react-native-reanimated can increase your app's memory usage by 25–30%, even if you don't actively use the library, due to a change in Hermes that shipped with React Native 0.85. As a workaround, enable worklets bundle mode. A fix is coming in Hermes V1 soon.
Upgrading your app
Try using our upgrade skills (installation instructions) with Claude Code, or a similar tool of your choice, to upgrade your app.
Here's how to upgrade your app to Expo SDK 56 from 55:
- Upgrade all dependencies to match SDK 56: npx expo install expo@^56.0.0 --fix
- Check for any possible known issues with Expo Doctor: npx expo-doctor@latest
- Refer to the "Deprecations" and "Notable breaking changes" sections above for breaking changes that are most likely to impact your app.
- Make sure to check the changelog for all other breaking changes!
- Upgrade Xcode if needed: Xcode 26.4 is required to compile a native iOS project. For EAS Build and Workflows, profiles without any specified image will default to Xcode 26.4.
- iOS deployment target bump: if you have any Expo modules of your own, update the iOS deployment target to 16.4 in your podspec.
If you use Continuous Native Generation:
- Delete the android and ios directories if you generated them for a previous SDK version in your local project directory. They'll be re-generated next time you run a build, either with npx expo run:ios, npx expo prebuild, or with EAS Build.
If you don't use Continuous Native Generation:
- Run npx pod-install if you have an ios directory.
- Apply any relevant changes from the Native project upgrade helper.
- Optionally, you could consider adopting prebuild for easier upgrades in the future.
If you use development builds with expo-dev-client: Create a new development build after upgrading.
If you use Expo Go: consider migrating to development builds. Expo Go is not recommended as a development environment for production apps.
Having trouble? Refer to the Troubleshooting your SDK upgrade guide.
Questions? Join our weekly office hours on Wednesdays at 12:00PM Pacific on Discord.
Thanks to everyone who contributed to the release!
Thanks to the Expo team — everyone contributed one way or another.
External contributors: Abhishek Raj, Aleksandr Kondrashov, Alfonso Curbelo, Amaury Liet, Andrej Pavlovic, Arthur Blais, Artur Morys - Magiera, Azeem Idrisi, azro352, benjamin, Benjamin Komen, Benjamin Wallberg, Błażej Kustra, C. Obama, CamWass, Choco, Chris Masters, Chris Zubak-Skees, Christian Wooldridge, Cristian C., Dalibor Belic, Daniel Meyer, Daniel Reichhart, Danish, Dave Mkpa-Eke, Delphine Bugner, Dennis Morello, desii, Dimitar Nestorov, Doğukan Yıldız, Donghoon Nam, Dwight Watson, Dylan, Emil Lindén, Eric Kreutzer, Eric Zeiberg, Fernando Rojo, Frank Calise, Gary Chiu, Gregory Moskaliuk, Gustavo Harff, Hugo Extrat, Ian K, Isaiah Hamilton, Jakub Kosmydel, Jc Cloete, Jeroen van Warmerdam, JeroenG, Jesper Sørensen, John HU, Jonathan Baudanza, Jonathan Rivera, Joseph Gift, Julie Saia, jurajpaska8, K.Dileepa Thushan Peiris, Kazuho Maejima, Kfir Fitousi, kimchi-developer, Kornelijus Šliubauskas, Kræn Hansen, Krastan Dimitrov, Kyle Ledbetter, Leonardo E. Dominguez, leonmetthez, Loic CHOLLIER, lucabc2000, Lucia Sarni, Manu, Matin Zadeh Dolatabad, Matthew Abraham, Mauko Quiroga-Alvarado, Maxime, Mikołaj Szydłowski, Mohammad Amin, Momtchil Momtchev, Myagmarsuren, Nicholas Pachulski, Nick Ater, Nicola Corti, Otávio Stasiak, Patrick Michalik, Patrick Wang, Patryk Mleczek, Peter Lazar, Petr Chalupa, Pflaumenbaum, Preet Patel, Randall71, Regi24, roach, Rodrigo Leite Araujo, Ronald Goedeke, Samuel Brucksch, Samuel Newman, Satyajit Sahoo, Sergiy Dybskiy, Serhii Pustovit, Shane Friedman, Shoghy Martinez, Shubh Porwal, Shubham Shinde, snowingfox, starsky-nev, teamclouday, Terijaki, TheUntraceable, ThiMal, Tomasz Zawadzki, Ty Rauber, Victor Bolivar De la Cruz, Vsevolod Lomovitsky, xoyseau, yerevin, and Zhovtonizhko Dmitriy.
Beta testers: Agrit Tiwari, Amrit Saini, androidanimation, Anthony Mittaz, Berhan, Brandon Austin, David Grimsley, dylanfcsr, Eduardo Lomelí, ifx326, Kenji Okura, Kingfapa, Lucas Hardt, Matthew Horan, Max, Robrecht Meersman, Rodolfo Perottoni, Simon, Sven.
Original source
Curated by the Releasebot team
Releasebot is an aggregator of official release notes from hundreds of software vendors and thousands of sources.
Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.