The React Native team released 0.88 on October 19, 2026. It bundles React 19.3.0, Metro 0.87 and Hermes 260318099.0.4, and it's the third release with no user-facing breaking changes, after 0.83 and 0.86. The release has 568 commits from 91 contributors. With 0.88 out, 0.85 moves to unsupported.
For most apps the upgrade from 0.87 needs no code changes. The release still deserves an afternoon, for two reasons: the event system underneath your handlers changed, and Apple's next SDK forces a lifecycle migration on iOS.
Events run through EventTarget
React Native now dispatches events through the W3C EventTarget API by default. The plugin-based dispatcher the renderer used since its first years sits behind an internal flag in 0.88, and the team plans to remove it. The announcement calls this the largest runtime change in the release. The React 19.3.0 bump unblocked it.
Events now travel a capture path down to the target and bubble back up through real event targets. capture, stopPropagation() and preventDefault() follow the DOM model instead of a React Native copy of it.
Your props don't change. onPress and friends keep their names, receive the same synthetic events with nativeEvent and persist(), and fire in the same order. onLayout and other direct events still fire on the target alone. The touch responder system stays as it was.
The code at risk reaches into React Native's event internals: libraries that registered plugins or patched the old dispatcher. The team asks you to report anything that works on the legacy path and breaks on the new one.
On the Canary channel, native refs expose the imperative API:
const ref = useRef(null);
useEffect(() => {
const onClick = event => {
// ...
};
ref.current?.addEventListener('click', onClick);
return () => ref.current?.removeEventListener('click', onClick);
}, []);
If an element has both a prop and an imperative listener for one event, the prop runs first.
Variable fonts
fontVariationSettings works on <Text> and <TextInput> on Android and iOS. It accepts the CSS string and an object:
<Text style={{fontVariationSettings: {wght: 700, slnt: -10}}}>Object form</Text>
<Text style={{fontVariationSettings: "'wght' 700, 'slnt' -10"}}>String form</Text>
Keys are four-character axis tags with finite numbers. If you load several static weights of one family to fake a variable font, you can ship one file instead.
iOS: SceneDelegate before Xcode 27
Starting with the iOS 27 SDK, Apple requires the UIScene lifecycle, and UIKit apps built with Xcode 27 that skip it fail to launch. React Native 0.88 adds support without removing the AppDelegate path. RCTReactNativeFactory gets two entry points:
startReactNativeWithModuleName:inWindow:connectionOptions:startReactNativeWithModuleName:inWindow:initialProperties:connectionOptions:
The migration has three parts:
| Step | Where |
|---|---|
Move the React Native entry point from AppDelegate to a SceneDelegate | ios/YourApp/SceneDelegate.swift |
Forward the scene's URL and user-activity callbacks to RCTLinkingManager | SceneDelegate.swift |
Add a UIApplicationSceneManifest key | Info.plist |
The community template already has both files, so diff against it in the Upgrade Helper. Support covers a single scene: keep UIApplicationSupportsMultipleScenes set to false. At launch, React Native forwards the first URL context or user activity from the connection options and drops the rest. Under UIScene the window can resize, and Dimensions.get() and useWindowDimensions() report the current values. Test deep links that arrive while the app is cold.
Swift Package Manager and CocoaPods
SwiftPM support stays experimental and opt-in in 0.88. The team published a schedule:
0.87
Experimental Swift Package Manager support arrives.0.88
Scripts hardened for more libraries and edge cases.0.89
SwiftPM becomes the target default, with a CocoaPods opt-out.
The team plans to drop CocoaPods in a later release. Library authors can now declare SwiftPM settings in a swiftpmConfig section of package.json. The SwiftPM block in react-native.config.js is deprecated.
Deprecations and quieter changes
react-native/Libraries/Core/InitializeCoreis deprecated. Importreact-native/setup-env.backgroundSize,backgroundPositionandbackgroundRepeatlose theirexperimental_prefix. The old names keep working as aliases.InputAccessoryViewon iOS is deprecated. The team points toKeyboardStickyViewfromreact-native-keyboard-controller.- Android's default
User-Agentnow includes your app name and version, as iOS does. A server that keys off the old string will see a new one. - Java TurboModules take and return
ArrayBuffer. Borrowed buffers in synchronous methods expire when the method returns, so copy the bytes if you keep them.
This week
- Upgrade a branch from 0.87 with the Upgrade Helper and run your test suite. Expo projects get 0.88 with SDK 58.
- Grep your dependencies for imports from React Native's event plugin internals, and file issues against libraries that use them.
- Start the SceneDelegate migration now, before Xcode 27 makes it a launch blocker, and test cold-start deep links on a device.
- Check your API logs and analytics filters for rules that match the old Android
User-Agent. - If you're on 0.85, schedule the jump. It no longer gets fixes.
Volodymyr Chornous

