The hidden cost of skipping a React Native upgrade
Postponing a React Native upgrade feels like saving engineering capacity. It's deferring it to a worse moment, with interest.
The compounding costs: each version skipped makes the eventual upgrade harder, more dependencies fall behind, CVEs accumulate, store-submission risk rises, and recruiting against an old stack gets noticeably harder.
The teams that regret the upgrade investment are rare. The teams that regret postponing it — once they're doing the emergency upgrade under a store-rejection deadline — are common.
You skip a React Native upgrade. Maybe one version. Maybe two. The app works. Customers don't notice. The team uses the freed capacity to ship features. The decision pays off.
For about a year.
This post is what happens after that year. The costs that don't show up on a roadmap but show up on every engineering meeting from then on.
Upgrade debt compounds
A one-version upgrade — say, 0.74 to 0.75 — is small. The upgrade helper renders a clean diff, you apply it, dependencies mostly slot in, you test, you ship. A team that does this every quarter spends a few engineer-weeks a year on upgrades and stays current indefinitely.
The same team that skips for two years isn't behind by two upgrades. It's behind by the cumulative drift of everything that pinned to React Native versions in between. Reanimated bumped, React Navigation bumped, the New Architecture flipped to default, Gradle bumped, Cocoapods bumped, the JS bundler changed defaults.
The shape of the cost curve isn't linear. The first version is cheap. The second is roughly the same. By the fourth or fifth, the work is no longer "upgrade React Native" — it's "upgrade React Native, the build tooling, half the dependencies, the native modules, and the privacy manifests, simultaneously."
A team that does its first upgrade in three years usually budgets 2 weeks. The actual upgrade takes 8–12 weeks. The variance isn't because the team is bad at estimating; it's because the dependent work was invisible until they started.
CVE exposure
React Native itself has a small CVE history. The framework's surface area for security issues is narrow. What's broad is the dependency graph it pins.
Each React Native release ships with a specific set of dependency versions in its template. When you stay on an old React Native release, you stay aligned with old versions of:
- Underlying iOS Cocoapods (some of which have shipped CVE fixes)
- Underlying Android Gradle plugins and Maven dependencies
- JavaScript packages whose newer versions patched issues you're not getting
- The bundler, which has had its own security history
You can manually upgrade individual dependencies inside an old React Native version — overrides, resolutions, force-pinning. But every override is one more thing to maintain, and at some point the override graph itself becomes a maintenance project.
Recent receipts: the 2024 Axios CVE chain hit teams whose old React Native version was still pulling an unpatched Axios through a transitive dependency. The 2025 @react-native-aria typosquat reached apps whose dependency graphs hadn't been audited recently. Each one was preventable with current dependencies.
Store-submission risk
Apple and Google don't reject apps for running old React Native versions. They reject apps for failing current submission requirements.
What's changed in the last 18 months:
- Apple privacy manifests. Enforced for SDKs in 2024. Old React Native versions don't ship a manifest. You can backport one, but it's fragile.
- Apple required-reason APIs. Enforced. Old library versions don't declare reasons. You replace them or fork them.
- Google Play target SDK. Google enforces a target SDK floor each year. Old React Native build configurations target old SDKs by default. Upgrading the target SDK in isolation often breaks the old build.
- Android 14+ behavior changes. Foreground services, photo picker, partial media access — old React Native versions don't handle these defaults gracefully.
The pattern: a team submits a routine update. It gets rejected. They scramble to figure out which requirement they missed. The fix turns out to require upgrading React Native, which they thought they had another year to defer.
The dependency graph drifts away from you
Library authors publish for current React Native versions. Their peer dependency ranges encode "what we tested against." When they update, the range moves forward and drops the older version.
You stay on 0.70. A year later, half your libraries have published new versions that no longer support 0.70. You're stuck on old versions. Those old versions in turn pin old dependencies. You stop being able to install new libraries cleanly because the ecosystem assumes a more current base.
The result: every new dependency becomes a project. Every new feature that requires a new library involves negotiating with peer ranges, ERESOLVE errors, and forks.
Recruiting and retention friction
The market for React Native engineers is asymmetric. The supply is large; the supply that wants to work on years-out-of-date React Native is small.
You'll see this in two places:
- Hiring. Candidates ask about the stack. They hear "React Native 0.69." They politely move on. The candidates you do attract are often less senior or specifically open to upgrade work — which is fine for one role, awkward for a team.
- Retention. Engineers join, do their job for a year, and then start asking when the upgrade is happening. When the answer is "we keep deferring it," some of them update their resumes.
This is harder to put on a spreadsheet than CVE risk or store rejections, but every engineering manager who's lived through it knows what it costs.
The emergency upgrade pattern
The cost of skipping isn't paid evenly. It's paid in one event, called "the upgrade we couldn't postpone anymore."
Common triggers:
- An App Store rejection that requires a current React Native version to fix
- A high-severity CVE that affects a library version your old React Native pins
- A required new dependency that won't install against your current setup
- A senior engineer leaving and the team realizing only they understood the patches
The upgrade gets attempted under deadline. It stalls. Features stop shipping. Engineering morale takes the hit. The actual engineering cost is higher than it would have been; the opportunity cost is much higher.
The actual math
Numbers from teams we've worked with. Variance is real, but the shape is consistent.
| Path | Engineering cost | Risk profile |
|---|---|---|
| Upgrade every minor version, in-house | ~2 engineer-weeks per quarter | Low. Predictable. Capacity stays free for features. |
| Upgrade once a year, in-house | ~3–4 engineer-weeks annually | Moderate. Manageable as long as it's actually done. |
| Skip for 18+ months, then catch up in-house | ~8–12 engineer-weeks, often stalled | High. Often blocks feature work. Frequent abandonment. |
| Skip for 18+ months, then catch up via productized service | 2–6 weeks, fixed price | Low. External team owns the risk, internal team keeps shipping. |
| Skip indefinitely until forced | Unbounded. Often a partial rewrite. | Severe. The forcing event is usually a deadline. |
The decision people often think they're making — "should we upgrade now, or save the effort?" — isn't the right framing. The right framing is "do we pay now, in scheduled chunks, or pay later under emergency conditions and at multiples?"
How far behind are you, actually?
Run the free scanner against your lockfile to see the version drift, the known CVEs, and the libraries that have already moved on without you. You'll have a real number to argue with — much better than a feeling.
Frequently Asked Questions
Is it OK to skip a React Native version?
Skipping one minor version is usually fine. The upgrade helper supports stepping by single versions, and most libraries support a small range. Skipping three or more versions is where the cost curve bends upward — dependencies that worked across versions 0.71 to 0.73 may break entirely on 0.76, native build configurations change, and the breaking-change list compounds. The right question isn't "can we skip?" but "how far behind is too far?"
How much does it cost to skip a React Native upgrade?
It depends what you're measuring. Direct engineering cost compounds — an upgrade that would have been 2 weeks at one version behind becomes 8 weeks at four versions behind. Indirect costs add up too: known CVEs in libraries you can't update, store-rejection risk from privacy manifest and target-SDK requirements, and developer recruiting friction because engineers don't want to work on years-out-of-date stacks.
What CVEs apply to old React Native versions?
React Native itself has had a handful of CVEs, but the bigger exposure is the dependency graph. Each React Native release pins a set of underlying libraries (Cocoapods, Gradle plugins, JS dependencies). When you stay on an old React Native version, you stay pinned to old versions of those — including some that have known vulnerabilities patched in later releases. The Axios CVE chain in 2024 and the @react-native-aria typosquat in 2025 both surfaced this exposure for teams that hadn't upgraded.
Why does the React Native upgrade get harder over time?
Two compounding forces. First, libraries drop support for old React Native versions as they update their peer ranges. The longer you wait, the harder it gets to find a version of each library that works against your old framework. Second, build tooling moves on — Xcode, Gradle, JDK, and Cocoapods all bump versions, and old React Native often doesn't work with current build tools. You end up needing to upgrade build tooling, dependencies, and the framework simultaneously, which is much harder than doing each separately.
Will Apple or Google remove my old React Native app from the store?
Not directly — they don't enforce framework versions. They enforce target SDK requirements, privacy manifest requirements, and a few other compliance items. Old React Native versions often can't meet those requirements without a manual backport, which is harder than upgrading. The store doesn't reject for being on React Native 0.68; it rejects because the React Native 0.68 build can't pass current submission requirements.
What's the breakeven point on a React Native upgrade?
For most teams, you break even on the upgrade investment within 6–12 months — through reduced CVE exposure, faster onboarding for new engineers, ability to use current libraries, and not having to do an emergency upgrade under a store-rejection deadline. The teams that report regretting the upgrade investment are vanishingly rare. The teams that regret postponing it are common.