React Native releases usually bring a mixture of JavaScript changes, native changes and developer tooling improvements.
React Native 0.87 is a good example of that.
It was released in August 2026 and introduced several changes that developers will notice mainly when working on the development environment and native project configuration. The most important changes are the Strict TypeScript API becoming the default JavaScript API, a newer and faster Metro version, experimental Swift Package Manager support for iOS, and Android Gradle Plugin 9 support.
For developers maintaining an existing React Native application, this release is interesting but it is not a version I would upgrade without checking the native project first.
What is important in React Native 0.87?
The main changes can be grouped like this:
Strict TypeScript API
↓
Cleaner and more stable JavaScript API
Metro 0.87
↓
Faster and lower-memory development tooling
Swift Package Manager
↓
New iOS dependency option
AGP 9
↓
New Android build requirements
Node 22 + Kotlin 2.0+
↓
New minimum toolchain requirementsThe release also contains many smaller fixes and improvements, but these are the areas most likely to affect an existing project.
Strict TypeScript API is now the default
One of the biggest changes is that React Native's public JavaScript API is now the Strict TypeScript API by default.
This was not introduced suddenly in 0.87.
React Native started moving toward this API earlier, with the API available as an opt-in preview in 0.80 and the older deep-import approach being deprecated. In 0.87, the strict API becomes the default public API.
For developers, this means I would be more careful about imports that go deep into React Native internals.
For example, older code can sometimes contain imports that reach into internal package paths instead of using the public React Native API.
The safer approach is to use the public API whenever possible.
For example:
import { View, Text, Platform } from 'react-native';instead of depending on internal implementation paths.
This may seem like a small difference, but it becomes important when the framework changes internally.
Why a strict public API is useful
When a framework has many internal modules exposed to developers, applications can accidentally become dependent on implementation details.
Then an internal refactoring can break application code.
A stricter API creates a clearer boundary:
Application
↓
Public React Native API
↓
React Native internalsInstead of:
Application
↓
Public API
+
Internal APIs
+
Undocumented importsFor large mobile projects, I prefer the first approach.
It reduces the number of internal assumptions in the application.
Metro 0.87 is a major part of this release
Metro is the JavaScript bundler used by React Native.
Most developers interact with Metro every day, even when they don't think about it.
When you run your React Native application, Metro is involved in:
JavaScript bundling
Module resolution
Source maps
Development updates
Dependency processingReact Native 0.87 updates Metro from 0.84 to 0.87.
The React Native team reports that source map generation is now about 2× faster and that Metro uses about half as much memory through more efficient source map storage. These are upstream benchmark observations, so the exact result will depend on the project.
For a small project, you may not notice a dramatic difference.
For a large React Native repository, the difference can become more noticeable.
Why Metro memory usage matters
Imagine a project with:
500+ screens
1000+ components
Many dependencies
Large generated bundles
Large source maps
Multiple platformsNow imagine Metro using several gigabytes of memory while developing.
On a developer laptop, that can affect other processes:
VS Code
Android Studio
Browser
Database
Docker
Emulators
MetroA reduction in Metro memory usage can therefore improve the complete development experience, not just the bundling step.
This is especially useful for developers working on laptops with limited RAM.
TypeScript and ESM Metro configuration
React Native 0.87 also adds stable support for TypeScript and ESM configuration files for Metro.
For example:
metro.config.mtsis supported.
At the same time, some older configuration approaches were removed, including .es6 extensions and YAML configuration support.
This is another example of why I would inspect the project before upgrading.
The question is not only:
"Does my React Native code work?"It is also:
"Does my Metro configuration still work?"Metro resolver improvements
React Native 0.87 also includes resolver improvements, including package self-resolution.
This is more of a tooling-level change than something most developers will directly use in application code.
But resolver changes matter because Metro has to understand the dependency graph correctly.
When working with:
Monorepos
Local packages
Shared components
Internal libraries
Workspace dependenciesmodule resolution becomes much more important.
This is one reason I always test monorepos separately after React Native upgrades.
Swift Package Manager support for iOS
Another major feature in React Native 0.87 is experimental support for Swift Package Manager, or SwiftPM.
The important word is:
experimental
React Native says this support is opt-in and additive, while CocoaPods remains the default and supported path. The release notes also explicitly say not to use the SwiftPM path in production yet.
So I would not immediately move a production iOS application from CocoaPods to SwiftPM just because 0.87 supports it.
I would test it separately.
Why SwiftPM is interesting
iOS projects have traditionally relied heavily on CocoaPods for dependency management.
With Swift Package Manager, the dependency flow can look different.
Conceptually:
Current
React Native
↓
CocoaPods
↓
iOS dependencies
Experimental
React Native
↓
Swift Package Manager
↓
iOS dependenciesReact Native's implementation uses the same prebuilt XCFrameworks that it already publishes, and the SwiftPM path is intended to work as an alternative package-management route.
For developers maintaining native iOS projects, this is something to keep watching.
Headers changed for SwiftPM
One of the more technical changes in 0.87 is around native headers.
To support SwiftPM properly, React Native changed how some precompiled binaries and headers are packaged.
Two new header-only frameworks are introduced:
ReactNativeHeaders.xcframework
ReactNativeDependenciesHeaders.xcframeworkThe React Native team also notes that bare-form header imports need the React namespace.
For example:
#import <RCTAppDelegate.h>becomes:
#import <React/RCTAppDelegate.h>for affected imports.
This is one of the changes I would specifically search for in an application with custom native iOS code.
If your project contains Objective-C or Objective-C++ code, don't assume the React Native upgrade is only a JavaScript change.
Android Gradle Plugin 9 support
React Native 0.87 is also the first React Native release to add support for Android Gradle Plugin 9.
AGP 9 itself contains breaking changes.
That means Android developers should pay attention to the native project configuration.
React Native's release guidance recommends opting out of AGP 9's built-in Kotlin and new DSL behaviour for now:
android.builtInKotlin=false
android.newDsl=falseThe React Native team notes that these opt-outs are expected to be removed starting with AGP 10.x.
This is exactly the kind of upgrade detail that can break a project even when all your JavaScript code is correct.
Node.js 22 is now required
React Native 0.87 also raises the minimum Node.js version to:
Node.js 22The release also raises the minimum Kotlin version to:
Kotlin 2.0+and introduces AGP 9 support.
This means the development machine, CI server and build server all need to be checked.
A developer can have:
Local machine → Node 22while:
CI → Node 20and suddenly the project fails only in CI.
I have seen this kind of environment mismatch many times in development projects.
The version should be consistent across the team.
Check your Node version
Before upgrading an existing project, I would run:
node -vThen check:
npm -vand:
npx react-native --versionThe exact CLI setup can vary between projects, but the important thing is to verify the actual environment instead of assuming it is compatible.
React Native 0.87 and existing applications
For a new project, using the latest stable React Native version is usually simpler than upgrading a project that has been running for several years.
An old application might contain:
Old Gradle configuration
Old Kotlin version
Old Xcode settings
Old CocoaPods dependencies
Custom native modules
Deep imports
Old Metro configuration
Outdated third-party packagesReact Native 0.87 can expose these issues.
That does not mean the release is bad for old applications.
It means the application has more migration work.
Upgrade the project step by step
For an existing React Native application, I would use the official React Native Upgrade Helper instead of manually guessing every native-file change. React Native's 0.87 release documentation specifically recommends the Upgrade Helper for comparing changes between versions.
My basic process would be:
Create upgrade branch
↓
Check Node version
↓
Check React Native version
↓
Check TypeScript
↓
Check Metro configuration
↓
Check Android Gradle files
↓
Check Kotlin
↓
Check iOS native code
↓
Run Android build
↓
Run iOS build
↓
Test applicationI would not mix the React Native upgrade with five other major dependency upgrades at the same time.
That makes debugging much harder.
Check third-party native packages
This is especially important.
A React Native application can depend on many native packages:
Push notifications
Maps
Camera
Payments
Bluetooth
PDF
File systems
Authentication
Analytics
StorageSome packages contain native Android or iOS code.
A package that worked with one React Native version may need an update for another.
So I check:
npm outdatedThen review native dependencies individually.
I don't automatically update everything.
I first identify which package is actually involved in the React Native upgrade.
Don't forget Android
A developer may run:
npm run androidand see that the application starts.
That is not enough.
I also test:
Debug build
Release build
Fresh install
Upgrade install
Deep links
Push notifications
Permissions
Background processingSome native issues appear only during release builds.
Don't forget iOS
The same applies to iOS.
I test:
Debug
Release
Clean build
Fresh install
Existing app upgrade
Permissions
Native modules
Push notifications
Deep linksAnd if the project contains custom native code, I specifically check the header changes introduced by 0.87.
Expo developers
Expo projects are a little different because the React Native version is tied to the Expo SDK and release channel.
The React Native 0.87 release announcement says React Native 0.87 would be available through expo@canary releases at that time.
So I would not manually force a React Native version inside an Expo project without checking the Expo compatibility matrix and the SDK version being used.
For Expo:
Expo SDK
↓
React Native version
↓
Expo native modules
↓
iOS / Android buildThese pieces need to remain compatible.
Is 0.87 faster?
There are improvements that can make development tooling faster, especially through Metro.
But I would not describe React Native 0.87 as:
"Your mobile app will automatically run faster."That is too broad.
The reported Metro improvements mainly affect the development and bundling process.
Application runtime performance depends on many other things:
JavaScript code
Rendering
Network calls
Database/API performance
Images
Animations
Native modules
Memory usage
Hermes
Device hardwareA faster Metro developer workflow and a faster production application are not the same thing.
This distinction is important when evaluating framework upgrades.
What I would check before production
For a production application, my checklist would be:
✓ Node.js 22+
✓ Kotlin 2.0+
✓ AGP configuration checked
✓ Metro configuration checked
✓ No unsupported deep imports
✓ Third-party native packages checked
✓ Android debug tested
✓ Android release tested
✓ iOS debug tested
✓ iOS release tested
✓ Push notifications tested
✓ Deep links tested
✓ Permissions tested
✓ App upgrade tested
✓ CI environment updatedFor large applications, I would also test on real Android and iPhone devices instead of relying only on emulators.
One important point about 0.87.1
When working with the 0.87 release line, don't stop at the original 0.87.0 release.
The React Native repository currently lists 0.87.1 as the latest 0.87 patch release, with fixes including an Android runtime issue around getInitialURL and a custom-font issue in the New Architecture.
So when upgrading to the 0.87 series, I would normally use the latest available 0.87 patch rather than intentionally staying on 0.87.0.
What this release means for developers
I think React Native 0.87 is mainly a developer tooling and native infrastructure release.
The most visible changes are:
Strict TypeScript API
+
Better Metro
+
SwiftPM experiment
+
AGP 9 support
+
New Node/Kotlin requirementsNone of these means we need to rewrite our React Native screens.
A component like:
function UserProfile() {
return (
<View>
<Text>User Profile</Text>
</View>
);
}is still the same.
The difference is everything underneath it.
Final thoughts
React Native 0.87 is an important release for developers maintaining modern mobile applications.
The Strict TypeScript API creates a clearer public API boundary.
Metro 0.87 improves source-map performance and memory usage.
Swift Package Manager gives iOS developers a new experimental dependency-management option.
AGP 9 support modernizes the Android build environment.
At the same time, Node.js 22, Kotlin 2.0+ and the Android build changes mean that an upgrade should be treated as a real development-environment upgrade rather than only changing one package version.
For a new React Native project, these changes are relatively straightforward to adopt.
For an existing production application, I would upgrade carefully, check native dependencies, update the development and CI environments, and test both Android and iOS release builds.
The biggest lesson for me is this:
React Native upgrade
≠
Change package version onlyIt is:
React Native
+
Node
+
TypeScript
+
Metro
+
Android Gradle
+
Kotlin
+
Xcode
+
Native dependencies
+
CIWhen all of these are checked together, a React Native upgrade becomes much easier to control.