Expo SDK 58 beta opens with iOS 27 support and a faster build pipeline
DEV Community

Expo SDK 58 beta opens with iOS 27 support and a faster build pipeline

You update your simulators, iOS 27 drops, and every app you haven't rebuilt yet either misbehaves or just looks wrong on the new scene-based life cycle. That's the situation SDK 58 is built to get ahead of. The SDK 58 beta starts today and runs three to four weeks. It's your window to test the new release against your app's specific configuration before it goes stable, and the Expo team will be shipping fixes and improvements throughout. SDK 58 targets iOS 27 and ships React Native 0.88 (Release Candidate), since 0.88 itself hasn't been tagged stable yet. Full release notes land with the stable release, but you can already dig through the changelogs in the expo/expo repository to see the scope, and everything will get merged into the root CHANGELOG.md once the beta wraps. For now, Expo Go on SDK 58 is available through Expo CLI for Android devices/emulators and iOS simulators, and through eas go for physical iOS devices. The App Store and Google Play builds of Expo Go will pick up SDK 58 shortly after stable ships, giving you time to migrate before the store version drops SDK 57. If you want to help test, the team is running office hours on Discord. Here's what's in the beta. Built for iOS 27 iOS 27 requires the UIKit scene-based life cycle and makes iPhone apps resizable by default, both of which apps built with the iOS 27 SDK inherit automatically. Expo apps now use the scene-based life cycle so they launch correctly (#46733); if you customize AppDelegate.swift, read the scene life cycle migration guide before you upgrade, since app delegate callbacks are delivered differently now. Expo packages also stopped reading geometry from UIScreen.main in favor of scene-aware helpers in expo-modules-core (#48172, #48168). Two behavior changes worth knowing: requireFullScreen no longer opts your app out of resizing on iOS 27, and ScreenOrientation.lockAsync may not do anything while the app is resizable, see orientation locks on iOS 27. And expo-glass-effect now reports isLiquidGlassAvailable as true for apps built with the iOS 27 SDK. EAS Build images with Xcode 27 are coming soon; until then the latest image ships Xcode 26.6. Device Hub support. Xcode 27 replaces Simulator.app with Device Hub, and Expo CLI detects it, boots simulators through it, and focuses the right device via its devices:// deep link. If you'd rather stay in the browser, install the new dev tools plugin: npx expo install expo-device-hub Run npx expo start and the link prints in your terminal. You get a live stream of every iOS simulator and Android emulator, tap/swipe/type interaction, boot/shutdown controls, CPU/memory/network graphs, and toggles for appearance, Liquid Glass, text size, and accessibility. If you don't have Xcode or Android Studio installed locally, keep an eye on EAS Simulator, a cloud simulator service in the works. expo-device-hub streaming an iPhone 17 Pro Max simulator running iOS 27. Source: Nathan Schroeder's post on X. App Intents: hand your app to Siri expo-app-intents exposes Apple App Intents (Siri, Shortcuts, Spotlight, Apple Intelligence) from your JavaScript (#47207). You declare intent types in Swift inline modules inside an app-intents directory, because Apple's build-time metadata extraction only reads code in the app target. The package routes invocations to JS and stores entity values. Scaffold it with npx expo-app-intents init . In practice: an onboarding app declares a "complete task" intent and a task entity. Ask Siri to complete a task, Siri lists your app's tasks, you pick one, and the intent runs in JS and marks it done, no need to foreground the app. An App Intent exposed from an Expo app: Siri asks which task to complete, then runs the intent in the app. This library is in alpha, with docs and examples coming. Expo UI: native navigation, more Compose components, actual visuals Every component in the Expo UI reference now has a screenshot next to its API, so you can see what you're picking before reading the props. Browse the SwiftUI and Jetpack Compose galleries. A sample of the SwiftUI and Jetpack Compose component galleries in the Expo UI docs. On iOS, @expo/ui adds NavigationStack , Toolbar , NavigationLink , NavigationDestination , the navigationTitle modifier, and a close button role, plus two and three-column layouts for NavigationSplitView . Several SwiftUI modifiers (background , tint , border , strokeBorder , foregroundStyle , and others) now accept any ShapeStyle , so you can paint a view with a material or gradient instead of just a color. On Compose, you get new Image , DateRangePicker , DateRangePickerDialog , and VerticalSlider components. Across both platforms, BottomSheet gains contentPadding , containerColor , and contentColor , and on web it drops the unmaintained vaul in favor of an in-house implementation. Also fixed: views hosted inside are now measured where SwiftUI/Compose actually placed them, which resolves dropped presses, stolen gestures, and missing touches inside BottomSheet , Popover , AlertDialog , and DropdownMenu . EAS Observe, now built into the SDK EAS Observe, generally available since August 20, gets deeper expo-observe integration in SDK 58: Observe.registerIntegration , ObserveErrorBoundary and reportError , an errorHandlingEnabled option, an expo-image integration, and Observe.clientId recorded on every event. AppMetrics is deprecated in favor of Observe . The EAS Observe overview: startup metrics, crash-free rates, and errors compared across releases. @expo/agent-cli: a CLI meant to be driven by an agent, not you Agents kept learning Expo the hard way: launch Expo Go, hit a runtime error on an unsupported native module, guess that you need a development build, then figure out when to reach for Expo CLI versus EAS CLI. @expo/agent-cli sits on top of both plus expo-doctor and falls back to Expo CLI, so you can just tell your agent to use it. Useful commands: status checks Expo Go compatibility without starting anything, dev starts the app with one command (deciding whether a build is needed and picking the fastest path), smoke is dev plus a screenshot plus stop, a quick check that the project actually runs on your machine, and skills:sync sets up co-located agent skills from node_modules. Start with: npx @expo/agent-cli@latest agents:setup then tell your agent to use @expo/agent-cli in place of Expo CLI. A shorter alias, expo-agent-cli , is also available (thanks to Kazutoyo Tokai for handing over the name). This is under active development, try it and file feedback. Home screen widgets land on Android expo-widgets now has an Android implementation: widgets run their own JS bundle on a dedicated Hermes runtime, with interaction support and Material Colors. On iOS, Live Activities pick up a staleDate option on start() /update() , stable ActivityKit identifiers, and runtime configuration changes. See the expo-widgets docs. Groundwork for Swift Package Manager builds React Native 0.87 added experimental Swift Package Manager support as an alternative to CocoaPods. SDK 58 restructures Expo's iOS sources so Swift, Objective-C, and C++ compile as separate SwiftPM targets, and an Expo autolinking plugin for npx react-native spm is in review, with a preview planned during the beta. CocoaPods stays the default, and precompiled Expo modules keep working there. Expo Modules: faster builds, faster calls, and a much simpler API expo-modules-core now ships precompiled native libraries for Android instead of compiling libexpo-modules-core.so from source on every clean build, CI run, and EAS Build. In our test on a blank SDK 58 project, a clean Android debug build across all four ABIs dropped from about 80 seconds to about 39 seconds on an Apple M3 Pro, roughly half, with bigger savings on machines with fewer cores like most CI runners. On the call-overhead side, SDK 56 already cut iOS calls 1.6 to 2.3x and made Android Record conversion around 6x faster by replacing reflection with a Kotlin compiler plugin. SDK 58 takes another pass at iOS: cheap calls cost less, long strings move up to 3.8x faster in either direction, and async function promises are cheaper to create and resolve. None of this needs adoption, every Expo module gets faster on SDK 58, including ones you didn't write. The bigger change is Expo Modules 2.0, now in beta on both platforms. Instead of describing a native module inside a DSL, you write an ordinary Swift or Kotlin class and annotate what you want exposed to JS, which is also a much easier shape for coding agents to generate since there's no custom DSL to explain. Because the binding is generated at build time from those annotations instead of resolved at runtime, it's faster again: synchronous calls are 2.5 to 5.6x faster than the DSL on an iPhone 16 Pro release build. On Android, across twelve microbenchmarks, Expo Modules 2.0 beats Expo Modules 1.0 in every case (1.2x to 39.9x) and beats TurboModules in every case too, for example a no-argument call takes 112 ns versus 2,837 ns for a TurboModule. Android microbenchmarks for Expo Modules 2.0 against Expo Modules 1.0 and a TurboModule. Lower is better. Docs are coming during the beta; the early look post has the full benchmark and API walkthrough. Fingerprint changes less often Bumping a version number or touching files inside node_modules used to invalidate your fingerprint for no good reason. SDK 58 defaults fingerprint to the balanced preset: it ignores routine changes like version in app.json and hashes native modules by package name and version instead of their files. Result: fewer unnecessary native rebuilds triggered by fingerprint mismatches. See fingerprint presets if you want a different tradeoff. An experimental Rust transformer that halves cold bundling time Metro's cache keeps warm bundles fast, but cold bundles (a fresh project, or a changed module) spend most of their time in Babel. SDK 58 introduces "Noxcturnal," an experimental module transformer written in Rust on oxc and exposed to Nod

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.