A Flutter or React Native app written three or four years ago. It works, users are happy, and nobody has touched it since the last release. Now an update has to go out — because the store requires a new targetSdk, because there is a bug to fix, or because there is finally budget for a new feature. The developer runs flutter build or npx react-native run-android and gets several hundred lines of errors.
It is one of the most common situations in the projects we take over. The good news: updating an old Flutter or React Native app can almost always be done without rewriting it from scratch. You just need to know exactly what has aged and in what order to upgrade it.
Why a cross-platform app ages twice over
A native app depends on two things: Android and iOS. A Flutter or React Native app depends on four layers that age at different rates:
- Store requirements — since 31 August 2026 Google Play has required updates to target Android 16 (API 36), and since 28 April 2026 the App Store has only accepted apps built with Xcode 26.
- Native tooling — Gradle, the Android Gradle Plugin, the Java and Kotlin versions, Xcode, CocoaPods.
- The framework — Flutter and Dart, or React Native.
- Libraries — packages from pub.dev or npm, each with its own native part.
The problem is that these layers are coupled. To meet a store requirement, you have to upgrade the native tooling. The new tooling does not work with the old framework. The new framework does not work with the old libraries. And some of the libraries stopped being maintained over the years. That is why “just bump targetSdk” in a neglected cross-platform project turns into an update of the whole stack. We cover the Google Play deadline itself in more detail in the article on why an app disappears from Google Play after the target API deadline.
Flutter: what usually blocks the update
Null safety and Dart 3. Since Flutter 3.10 (May 2023), Dart requires full sound null safety. A project that never went through the migration will not compile on any recent version of Flutter. The migration can be partly automated, but in a large codebase it is still the most labour-intensive part — and it requires understanding which values can actually be null.
Gradle configuration. Projects created before 2023 apply the Flutter Gradle plugin in the old, imperative style. Newer versions of Flutter require the declarative style (the plugins {} block). The official migration guide describes this step by step, but in projects with custom changes to the Gradle files something unexpected always comes up. Very old projects may still use the first version of Flutter’s Android embedding (v1 embedding), support for which has been removed.
Abandoned packages. pub.dev marks packages as discontinued, often pointing to a successor. The flutter pub outdated command shows how far behind the dependencies are; after updating, dart fix --apply automatically fixes some of the API changes.
React Native: what usually blocks the update
The New Architecture. Since version 0.76 (October 2024), React Native has used the New Architecture by default, and since version 0.82 (October 2025) the old architecture is no longer supported. An app on a version earlier than 0.76 therefore has to move to the New Architecture — which means every library with native code has to support it. The reactnative.directory catalogue lets you filter libraries on this. Libraries that were never updated have to be replaced, or their native part rewritten.
Jumping many versions. Every React Native version changes the project’s native files — build.gradle, Podfile, AppDelegate. The Upgrade Helper tool shows the differences between any two versions. When jumping a few versions, you can apply them by hand; when jumping a dozen or more, it is usually faster to create a clean project on the current version and move the app code into it than to fight through a chain of conflicts.
Expo. Expo projects have it easier, because Expo manages the native configuration. The recommended path is to upgrade one SDK version at a time and run npx expo install --fix after each one to align library versions. Projects that ejected at some point and have had manually modified android and ios directories ever since can be troublesome.
Minimum OS versions. Successive React Native releases — like Flutter’s — raise the minimum supported Android and iOS versions. Before updating, check the store statistics to see how many users are on the versions you will stop supporting.
Common to both: the native layer
Regardless of the framework, in 2026 you have to reckon with several native requirements:
- 16 KB memory pages on Android. Google Play requires apps targeting Android 15 and later to work on devices with 16 KB memory pages. This applies to native libraries (
.so) — and Flutter and React Native apps always have plenty of them, starting with the framework engine itself. Old versions of frameworks and libraries do not meet this requirement. - Edge-to-edge. With
targetSdk36, an app can no longer opt out of drawing behind the system bars — the UI has to handle insets correctly. - Xcode 26 and Liquid Glass. An app built with the new iOS SDK gets the new look for standard components. More on this in the article on what has changed in the new Android and iOS.
- CocoaPods. The CocoaPods team has announced that the central specs repository will become read-only at the end of 2026. Existing dependencies can still be installed, but new library versions will be published via Swift Package Manager. Flutter and React Native already support SPM — during a major update it is worth planning the move straight away.
An order that saves time
- Reproduce the current state. Before updating anything, build the app in its current version — even if that requires an old version of Flutter, Node, Java or Xcode. Without a working baseline you cannot tell bugs introduced by the update from bugs that have always been in the app.
- List the key flows. Login, payments, notifications, the most important screens. If the project has no automated tests, a checklist for manual testing is enough — but it has to exist before you start.
- Review the dependencies. Classify each library: update, replace, remove. It often turns out that some libraries are unused, or used for one small thing that is easier to write yourself.
- Choose a path. For a small jump — update version by version. For a large one — a clean project on the current framework version, with the code moved over. The second path looks bigger, but it is usually more predictable.
- Keep the update separate from new features. The first release after the update should look and behave exactly like the previous one. If something breaks, you will know where to look.
- Release gradually. Staged rollout in Google Play and phased release in the App Store let you release the new version to a share of users and watch for crashes before it reaches everyone.
How long updating an old Flutter or React Native app takes
It depends mainly on the size of the version jump and the state of the libraries, not on the size of the app. Roughly:
Situation Typical effort Framework a year old, libraries still maintained a few days Framework 2–3 years old, a few libraries to replace two to four weeks Flutter without null safety, or React Native from before the New Architecture with abandoned native libraries a month or more, depending on the amount of codeThese are ranges, not a quote — an exact figure can only be given after reviewing the project. Sometimes such a review shows that part of the app is better rewritten; we explain how to make that decision based on numbers in refactor or rewrite from scratch.
How not to end up here again in three years
Updating by one year is a few days of work. Updating by four years is a project. The difference is not that there are four times as many changes, but that they stack on top of each other and you have to work through all of them at once. The cheapest strategy is regular, small updates — the framework and libraries upgraded every few months as part of routine maintenance, together with the annual change in store requirements.
We update and maintain Flutter and React Native apps, including ones nobody has touched for years — through app reactivation and then mobile app maintenance. If you want to know how far behind your project is and how much work stands between it and the next release, order a free app analysis — you will get the results in writing.