News and analysis
Choosing a mobile stack with maintenance costs in mind
React Native, Kotlin and Swift: comparing dependencies, upgrades, team workflows and maintenance before choosing a mobile stack.
The cost of a mobile application also depends on how easily the team can change it after launch. Identical Android and iOS screens do not imply identical expenses: dependencies, builds, platform constraints and maintenance skills differ. Choose a stack against future working scenarios and add an upgrade plan to the development estimate.
Two events in the editorial source collection make this discussion timely. React Native 0.87 made the Strict TypeScript API the default public API, while access to internal package paths required migration. Swift Package Manager support in this version is experimental, and its authors explicitly recommend against using that route in production for now. These are facts about a specific release, rather than instructions to upgrade every application immediately. React Native 0.87 announcement.
JetBrains has announced the discontinuation of Swift editing and navigation support in the KMP plugin from the IDE versions specified in its publication. Running iOS applications, debugging Kotlin and Kotlin/Native capabilities remain available. Part of the working environment changes; iOS support in Kotlin Multiplatform is not being removed. JetBrains announcement.
Map platform risks first
Consider a hypothetical application for employees receiving goods and photographing damage. It includes authentication, scanning, an offline action queue and photo uploads. Its business value depends on completing receiving work in the warehouse. A polished shared interface cannot compensate for a lost record or a scanner that fails.
Before comparing technologies, test the hardest part: the actual device, required SDK, camera behaviour and recovery after the application closes. If only one supplier maintains a dependency, its availability and support become separate evaluation items. Record these conditions regardless of the language selected.
Then divide the application into layers: interface, business rules, local data, platform integrations and server. For each layer, establish what will be shared and who can investigate a failure. “Shared codebase” is too broad for a contract because it does not define responsibility boundaries.
Compare the team's work, not the number of languages
React Native is worth considering when the team can maintain React and JavaScript/TypeScript and a working prototype confirms the required platform features. Check both your code and packages with native components. A TypeScript specialist alone does not cover iOS builds, signing or Android dependencies.
For Kotlin Multiplatform, assess shared logic separately from the selected UI approach. If Swift remains in the application, provide a clear workflow for the Swift developer. An IDE change may affect everyday navigation, but does not establish a necessary cost of rebuilding the entire product.
Compare separate Kotlin and Swift applications against the same scenarios. The estimate will include two implementations of some behaviour and coordination of contracts. A team with strong platform expertise may nevertheless find this easier for maintaining complex integrations. There is no universal winner.
| What to compare | How to obtain evidence |
|---|---|
| Critical integration | Build a prototype on target devices |
| Dependency upgrades | Examine the previous and planned upgrade paths |
| Failure recovery | Repeat the scenario offline and after restarting |
| Maintenance handover | Ask a second developer to build from the instructions |
Estimate the cost of changing one scenario
Instead of unsupported savings claims, choose the same change for every option. For example, add a new receiving confirmation type, change the server contract and release both application versions. Estimate affected components, verification, release work and support for older clients.
Record the result as a work list with assumptions. Where is a new library needed? How will backward compatibility be checked? Are unfinished actions retained? Who updates build instructions? This explains the cost of development more accurately than counting screens.
Define recurring work separately: error monitoring, tool upgrades, system-permission checks and corrective releases. Estimate that effort for the specific project. A manufacturer's claim that a tool is faster does not prove a lower overall application budget.
What the decision should leave behind
Keep a short document describing the choice, verified constraints and conditions for revisiting it. A critical SDK losing support or a future scenario needing another offline model could trigger review. This makes the architectural decision testable.
A useful first release completes one working journey, including exceptions. This approach is described on the custom applications page. Prepare a list of devices, integrations, offline actions and team capabilities. It provides a basis to discuss the product and estimate development together with maintenance.
Define the application's boundary first
My experience includes a mobile application created for a project in South Africa that started from scratch. The public account confirms the application was built, but does not establish its mobile stack, maintenance cost or completion of the wider platform. I therefore do not use it as evidence for Flutter, React Native or native development. The useful question is which customer journey must work and where the server's responsibility begins.
My first customer portal release guide explores that question through one complete journey, permissions and available integrations. This makes it possible to compare proposals covering the same scope, including support and recovery beyond the application's first screen.
Sources
Facts checked on 7 October 2026. The recommendations analyse selection conditions; they are not measurements from a client project.