React Native 0.87 and SwiftPM in 2026: Modern iOS Build and Interview Questions

React Native 0.87 introduces experimental Swift Package Manager support, eliminating CocoaPods from iOS builds. This guide covers SwiftPM setup, the Strict TypeScript API, Metro 0.87 optimizations, and interview questions for senior mobile developers.

React Native 0.87 Swift Package Manager iOS build system illustration

React Native 0.87, released August 11, 2026, brings experimental Swift Package Manager (SwiftPM) support to iOS builds, marking the first step toward eliminating CocoaPods from React Native projects. This release also makes the Strict TypeScript API the default, ships Metro 0.87 with 2x faster source map generation, and raises minimum toolchain requirements to Node.js 22, Kotlin 2.0, and Android compileSdk 37.

SwiftPM Setup in One Command

After deintegrating CocoaPods, run npx react-native spm --deintegrate once. The project then auto-relinks native dependencies on each build without pod install.

Swift Package Manager Replaces CocoaPods for iOS Dependencies

SwiftPM support in React Native 0.87 is opt-in and experimental. CocoaPods remains the default dependency manager for production apps. The SwiftPM path consumes the same prebuilt XCFrameworks that React Native already publishes, so no additional binary downloads are required.

The key benefit: a SwiftPM-based project only needs Xcode. Ruby, Bundler, and CocoaPods are no longer required on developer machines or CI pipelines.

bash
# ios-swiftpm-setup.sh
# Step 1: Navigate to iOS directory
cd ios

# Step 2: Deintegrate CocoaPods and generate SwiftPM references
npx react-native spm --deintegrate

# Step 3: Open project in Xcode and build
open MyApp.xcworkspace

The spm --deintegrate command injects Swift package references into the existing .xcodeproj rather than replacing the project file. Code signing settings, build phases, and capabilities remain untouched. To reverse the change, run npx react-native spm deinit.

How SwiftPM Autolinking Works Without pod install

After the initial setup, dependency changes trigger automatic relinking. Install or remove a native package with npm or yarn, then build. The project detects changes and re-runs autolinking during the Xcode build phase.

bash
# dependency-workflow.sh
# Install a native dependency
npm install react-native-reanimated

# Build triggers automatic relinking
npx react-native run-ios
# No pod install required

For fresh clones and CI environments, run npx react-native spm once before the first build. This generates the Package.swift file and resolves Swift package dependencies.

SwiftPM Limitations and Production Readiness

SwiftPM support in 0.87 carries important limitations that affect adoption decisions:

LimitationImpact
Community library supportEach library must ship a Package.swift file
Command stabilityFlags and generated layout may change in 0.88+
CI configurationRequires npx react-native spm step before builds
DocumentationLimited troubleshooting resources available

For production applications, CocoaPods remains the recommended path. Teams evaluating SwiftPM should prototype on a branch and test their full dependency tree before committing to migration.

Ready to ace your React Native interviews?

Practice with our interactive simulators, flashcards, and technical tests.

Breaking Change: Namespaced iOS Header Imports

React Native 0.87 ships new XCFrameworks: ReactNativeHeaders.xcframework and ReactNativeDependenciesHeaders.xcframework. Native modules using bare-form angle includes must add the React/ namespace prefix.

AppDelegate.mobjective-c
// Before 0.87 - bare include
#import <RCTAppDelegate.h>
#import <RCTBridge.h>
#import <RCTRootView.h>

// After 0.87 - namespaced include
#import <React/RCTAppDelegate.h>
#import <React/RCTBridge.h>
#import <React/RCTRootView.h>

This change applies to both CocoaPods and SwiftPM builds. Projects with custom native modules need to update all header imports before upgrading.

Strict TypeScript API: The New Default JavaScript Interface

The Strict TypeScript API, previewed in 0.80, becomes the default in 0.87. Types are now generated directly from React Native source code, eliminating drift between the TypeScript definitions and actual runtime behavior.

component-refs.tsxtypescript
import { useRef } from 'react';
import { View, TextInput, ViewInstance, TextInputInstance } from 'react-native';

export function FormComponent() {
  // New dedicated ref types replace generic RefObject<T>
  const containerRef = useRef<ViewInstance>(null);
  const inputRef = useRef<TextInputInstance>(null);

  const focusInput = () => {
    // Type-safe method access
    inputRef.current?.focus();
  };

  return (
    <View ref={containerRef}>
      <TextInput ref={inputRef} placeholder="Email" />
    </View>
  );
}

Three breaking type changes require attention during migration:

  1. Deep imports blocked: react-native/Libraries/* paths now produce type errors. All exports must come from the root react-native package.

  2. Ref type updates: ViewInstance and TextInputInstance replace generic ref types. The *Properties type aliases are removed in favor of *Props.

  3. useColorScheme change: Returns ColorSchemeName | null instead of the previous 'unspecified' string value.

Opting Out of Strict TypeScript During Migration

Teams needing more time to migrate can restore legacy deep imports through React Native 0.88:

tsconfig.jsonjson
{
  "extends": "@react-native/typescript-config",
  "compilerOptions": {
    "customConditions": ["react-native", "react-native-legacy-deep-imports"]
  }
}

This escape hatch will be removed in React Native 0.89. Projects should prioritize migration before that release.

Metro 0.87: 2x Faster Source Maps and 50% Less Memory

Metro bundler version 0.87 ships with significant performance improvements that affect development workflow and React Native DevTools startup time.

Source map generation is 2x faster due to optimized string handling. DevTools now loads faster because source maps are generated more efficiently during development builds.

Memory usage drops 50% through more efficient source map storage. This matters for large codebases where Metro previously consumed significant RAM during long development sessions.

Additional Metro changes:

  • Stable support for TypeScript config files (metro.config.mts)
  • ESM config file support alongside CommonJS
  • Package self-resolve in the resolver
  • Dropped support for .es6 file extensions and YAML configuration files

Minimum Toolchain Requirements for React Native 0.87

This release raises minimum version requirements across the toolchain. CI pipelines and developer environments need updates before upgrading.

RequirementVersion
Node.js≥ 22.13.0
Kotlin≥ 2.0 (bundled: 2.2.0)
Android minCompileSdk34
Android compileSdk37
Android Gradle Plugin9.x

For AGP 9 compatibility issues, add opt-outs to android/gradle.properties:

properties
# android/gradle.properties
# Temporary opt-outs for AGP 9 migration
android.builtInKotlin=false
android.newDsl=false

Removed APIs in React Native 0.87

Several deprecated APIs are removed in this release. Projects using these APIs need refactoring before upgrading.

Removed APIReplacement
InteractionManagerrequestIdleCallback
Modal animated propUse default transition behavior
NativeMethods typeHostInstance
useTurboModules flagAlways enabled, flag removed
Touchable root exportExtend ViewProps directly
react-native/rn-get-polyfills@react-native/js-polyfills

Additional deprecations targeting future removal include ImageBackground (use View with absolutely positioned Image), DrawerLayoutAndroid (use react-native-drawer-layout), and react-native/Libraries/Core/InitializeCore (use react-native/setup-env).

React Native 0.87 Interview Questions for Senior Developers

These questions appear in senior mobile developer interviews following major React Native releases. Understanding the architectural decisions behind SwiftPM support and the Strict TypeScript API demonstrates framework-level knowledge.

Q: Why does React Native 0.87 introduce SwiftPM as experimental rather than replacing CocoaPods immediately?

SwiftPM support depends on community libraries shipping Package.swift files. Unlike CocoaPods where a central Podspec registry exists, SwiftPM requires each library author to add native Swift package configuration. The experimental phase allows the ecosystem to adopt SwiftPM gradually while CocoaPods remains stable for production apps. Additionally, the CLI commands and generated project layout may change based on developer feedback before stabilizing.

Q: What problem does the Strict TypeScript API solve that hand-maintained type definitions could not?

Hand-maintained type definitions drift from runtime behavior between releases. Internal refactors that change function signatures or add parameters may not be reflected in the types immediately, causing runtime crashes that TypeScript should have caught. The Strict API generates types directly from source code, making types authoritative rather than aspirational. It also blocks deep imports that access unstable internal APIs, preventing breakage when those internals change.

Q: How does SwiftPM autolinking differ from CocoaPods autolinking in React Native?

CocoaPods autolinking runs during pod install, which developers must remember to execute after dependency changes. SwiftPM autolinking runs during the Xcode build phase automatically. The build system detects dependency changes and regenerates the package manifest without manual intervention. This eliminates a common source of "it works on my machine" issues where developers forget to run pod install after pulling changes.

For additional React Native interview preparation, see the native modules deep dive and testing strategies question banks.

Ready to ace your React Native interviews?

Practice with our interactive simulators, flashcards, and technical tests.

Upgrade Strategy for React Native 0.87 Projects

The React Native Upgrade Helper generates a diff between the current project template and 0.87. This diff shows exactly which files need changes.

Prioritize these migration steps:

  1. Update Node.js to 22.13.0+ and verify CI environments match
  2. Run TypeScript compilation to identify deep import violations
  3. Update ref types from generic to dedicated instance types
  4. Update iOS header imports to namespaced format
  5. Test the full native dependency tree before enabling SwiftPM

For Expo projects, React Native 0.87 is available in expo@canary releases. Production Expo projects should wait for the stable SDK release.

What 0.87 SwiftPM Support Means for iOS Build Times

SwiftPM eliminates pod install from the development workflow, but initial project setup requires more time. The npx react-native spm command resolves Swift packages from source, which takes longer than downloading pre-built CocoaPods binaries.

Subsequent builds benefit from Xcode's incremental package resolution. Only changed packages are refetched. For teams with frequent dependency churn, this incremental approach may be faster than repeated pod install cycles.

CI optimization differs between the two approaches. CocoaPods caches Pods/ directories effectively. SwiftPM caches through Xcode's derived data, which requires different cache key strategies. Teams migrating CI pipelines should benchmark both approaches with their specific dependency set.

For related iOS build optimization techniques, see the React Native New Architecture guide covering Hermes V1 and bridgeless mode performance characteristics.

Start practicing!

Test your knowledge with our interview simulators and technical tests.

Daily challenge

Can you spot the bug in React Native?

One real snippet, one hidden bug, one attempt a day. No account needed to try.

Anthony Fillion-Maillet

Written by

Anthony Fillion-Maillet

Founder of SharpSkill

Full-stack developer for over 10 years. Runs SharpSkill and answers for everything published here.

Updated on September 3, 2026

Tags

#react-native
#ios
#swiftpm
#typescript
#mobile-development

Share

Related articles