Donate to support freedom.
Get the same

Legacy Mobile App Refactoring & Migration

We modernise legacy iOS and Android apps with staged Objective-C to Swift and Java to Kotlin migration, keeping every release shippable.

Legacy Mobile App Refactoring & Migration

An app that pays its own bills every month is a business asset. When the iOS build still carries a large Objective-C layer and the Android module runs Java against a Gradle setup from several years back, each new feature costs more than the last and every platform release means hunting for a library nobody maintains.

We migrate those codebases while the app keeps shipping. Objective-C moves to Swift in reviewable slices, Java moves to Kotlin, abandoned dependencies get replaced or deleted, and tests are written around the behaviour that already works. The store listing, subscribers, and release train stay put.

Why an ageing app is worth the work

Starting again from zero discards the parts that took the longest to get right. An app with years of installs has a review history, a subscription flow that passed review, and product logic that encodes hundreds of small decisions about sync, retries, and refunds. None of that comes back for free after a rewrite.

What the migration covers

Language and platform code

Objective-C and Java are the migrations we run most often. A class moves when a feature touches it, which ties the change to a reason and keeps the diff readable, and bridging headers, nullability annotations, and @objc exposure get cleaned up as it crosses. On Android the same approach covers Java to Kotlin conversion, platform types, and old callback or RxJava code moving to coroutines and Flow.

Dependencies that stopped being maintained

Library rot is the usual reason a build will not move forward: abandoned CocoaPods, a Firebase SDK several majors behind, deprecated Play Services, or a Gradle and JDK combination only one laptop can build. We inventory every dependency and either replace it or remove it, with CocoaPods moving to Swift Package Manager where the package allows it.

Build, tooling, and interfaces

Slow builds and unclear release steps cost a team more hours than most refactoring work, so we shorten build times, put the pipeline in a state anyone can run, and move screens to SwiftUI or Jetpack Compose as they are being changed. Mandatory platform deadlines and target SDK bumps are handled on our SDK and API version upgrade service, which often runs alongside this work.

Tests as the safety net

Refactoring without tests is guessing with a compiler. Where coverage is thin we write characterisation tests that record what the app does today on login, payments, and sync, and those tests run in CI so every migration phase has to keep them green. They also make an honest answer to "how fast can this go?" possible.

Who this is for

Teams whose app earns revenue but has become slow to change. Founders who inherited a codebase after the original developer left. Companies that acquired an app and need to understand it first. These codebases share one trait: people avoid touching them, so bugs live longer.

Where the project starts

The plan changes with what already exists.

A plain idea has nothing to migrate. If the product is still a sketch, we build it in Swift and Kotlin with a structure that keeps later change cheap, which is mobile app development.

An existing conventional codebase is the case this page covers. We audit it, map the modules, and migrate in phases while the app ships on its normal cadence.

An AI-built prototype is a different problem: quickly generated code tends to have no consistent architecture, so there is little to migrate and a lot to stabilise. That work belongs on our vibe-coded mobile app rescue page, and clients often move from there into migration once the structure holds.

What we deliver

An audit with a module inventory, a dependency list, and a ranked plan. Migration phases merged into the main branch and released through your existing store process. Test coverage on the paths that carry money and user data. A build pipeline a new developer can run on day one, plus written notes so the next engineer is not guessing.

How the engagement runs

The first week is an audit, because a migration priced from a guess becomes a dispute. We read the codebase, run the app, check crash and analytics reports if they exist, and give you a plan split into phases instead of one large estimate.

Work then proceeds in two to four week phases. Each phase takes one area, such as the networking layer, the subscription flow, or a group of screens, and ends with a merge and a release, so nothing sits on a long lived branch for months. A behaviour change users would notice goes behind a flag and can be reverted without another build. Dependency upkeep after migration usually continues under a monthly mobile maintenance arrangement.

Refactoring or rewriting

These are different projects with different risk. A rewrite is the right call when the data model cannot support what the product needs, when a platform constraint blocks a required capability, or when the code is so tangled that no module can be tested at all. It is the expensive answer, and it freezes the app while it runs.

Incremental migration wins whenever the app already works, and our portfolio shows why. HideX, published as CalculatorX, has a live App Store listing and a subscription product written in Swift, so a staged migration keeps that listing, its subscribers, and its accepted payment flow running while the code underneath changes. Easy VPN Free shipped from a 2017 Android codebase and stayed in public use for years, and its successor Voice VPN moved to new transport protocols as a deliberate new product, so the users it had were never reset.

What it costs

Migration work runs at our flat rate of $39 per hour, because scope is set by what your codebase contains rather than by a feature list. The audit is usually a fixed price once we have seen the repository, and after that we quote phase by phase in weeks so you can review or stop between them.

A mobile MVP built from scratch is a different kind of order, and it sits in the typical range of $4,800 to $8,500 across four to six weeks on the pricing page, which also lists capacity plans from $2,699 per month. That shape applies when migration uncovers features the product lacks. The same page explains both models, and you get a written scope before any code moves.

Proof

Voice VPN is our in-house privacy VPN: a Flutter app with native Android and iOS VPN layers, a credit and ad model, and automation for node rotation. It proves we maintain a product with deep platform integration over years, and that the native code behind a cross-platform interface is what a staged migration protects.

Easy VPN Free is an open-source Android VPN from 2017 that stayed usable and referenced for years, with community translations and a public repository. It proves an older app can stay supportable long after its architecture was chosen.

CalculatorX, published as HideX, is a native Swift privacy utility with a vault behind a disguised calculator, PIN access, and a recovery path. It proves we work in shipped Swift products where security behaviour and store review both matter, which is the environment a migration has to leave intact.

Related services

Next step

Send us the repository or a link to the store listing, tell us what has become painful to change, and we will say whether migration or a rewrite fits your case. You get a phased plan and a first estimate before anyone touches the code.

Contact us with a short description of the app and the platform it runs on, or run the scope through the Vasilkoff.info estimator to get a starting range on cost and timeline.