Skip to content
CipherCruCipherCru

Menu

Cross Platform App Development

Cross Platform Migration

Both directions are legitimate. Consolidating is not automatically progress, and separating is not automatically an admission — each is right when the arithmetic says so.

Typical duration
Five to fourteen months
Team shape
Three to five senior engineers
Starts with
A three-week assessment
A migration sequence planned out across two platforms

Screen by screen, with both versions shipping

The version of this that fails is the parallel rewrite: a new codebase built alongside the old apps, with a switchover date that moves twice and a roadmap frozen while everyone waits. Nobody plans it that way, and it happens anyway, because the apps keep changing.

We migrate incrementally instead. React Native and Flutter both embed into an existing native app, so screens move one at a time inside the shipping product — the app in the store is always the real one, and each moved screen is verified in the field before the next is scoped. Feature work continues throughout, which is the difference between a migration that finishes and one that gets cancelled at sixty per cent.

What usually goes wrong, and what we do instead

The technical work is well understood. The sequencing and the freeze are what go wrong.

Where platform migrations fail

  • A parallel rewrite with a switchover date that moves and moves again
  • A roadmap freeze announced for the migration, then quietly extended
  • Behaviour differences between old and new found by users, not by tests
  • The shared and native boundary decided screen by screen under pressure
  • Store release mechanics rebuilt late, so nothing can ship mid-migration

How we run it instead

  • Screens moved inside the shipping app, so there is only ever one product
  • Feature work continues, with slices sequenced around the roadmap
  • Behaviour characterised from the existing apps before anything moves
  • The boundary drawn and written down before the first screen moves
  • One release pipeline built in the first month, covering both stores

What changes, in practice

Taking consolidation as the common direction. The things that are different for the people who build and ship the apps.

Two apps today

Working, and everything happens twice.

  • A feature is specified once and built twice, by two teams
  • The two apps behave subtly differently and nobody knows where
  • A bug is fixed on one platform weeks before the other
  • Releases go out separately, and versions drift apart
  • Hiring is two skill sets, and holidays are two single points of failure
  • Business logic is implemented twice, so it diverges quietly

One codebase after

Same product, built once.

  • A feature is specified once, built once and tested once
  • Both platforms run the same business rules by construction
  • A fix reaches both platforms in the same release
  • One pipeline produces both store artefacts, so versions match
  • One skill set to hire for and to cover
  • The native boundary is documented, so what is not shared is deliberate

What the work involves

Whichever direction it runs, the shape of the work is the same.

Boundary design

What ends up shared and what stays native, drawn and written down before the first screen moves.

Characterisation

Tests written against what each existing app actually does, including where the two already disagree.

Incremental embedding

Screens moved inside the shipping app, so the store always holds the real product.

Native module ownership

The platform code that survives the migration, brought under test and documentation rather than inherited.

Field verification

Each moved screen measured on the slowest supported device and in the hands of real users before the next.

Reversibility

A moved screen can be routed back to the native implementation, and that path is tested rather than assumed.

How the migration runs

The same five stages as every engagement, applied to apps that cannot stop shipping.

Diagnose

What the apps do, where they already differ, and which screen is both valuable and safe to move first.

Decide

The direction, the framework, the boundary and the screen order, written down with what each one risks.

Prove

One screen moved and shipped to both stores inside the existing app, then routed back once to prove the path.

Deliver

Screens moved in sequence, each verified in the field before the next is scoped.

Hand over

Your team ships a release with us watching, then without us, and the replaced code is removed once nothing calls it.

What we move apps onto

The target depends on the direction and on who maintains it afterwards.

Shared

  • React Native
  • Flutter
  • TypeScript
  • Expo

Native

  • Kotlin
  • Swift
  • Jetpack Compose
  • SwiftUI

Data and services

  • SQLite
  • Firebase
  • PostgreSQL
  • GraphQL

Delivery

  • GitHub Actions
  • Gradle
  • TestFlight
  • Sentry

What you get, and when

Handed over as it is produced, not assembled at the end.

  • Where the two apps already behave differently, found rather than assumed
  • The boundary, and the screen order with its reasoning
  • What would change the plan, stated before it happens
  • Source in repositories you own
  • Characterisation tests pinning the original behaviour
  • A tested route back to the native implementation
  • One pipeline producing both store artefacts
  • Crash and performance dashboards split by platform and screen
  • A record of what has been replaced and what has been removed

What we work towards

ILLUSTRATIVE, pending sign-off. These are the measures a platform migration is judged on and the direction they should move — not results from a named engagement. They will carry real figures or be removed before launch.

Implementations per feature

TwoOne

Gap between platform fixes

WeeksSame release

Store versions in step

Frequently driftedOne pipeline

Roadmap paused during the work

The usual planNever

Rollback for a moved screen

A store releaseA routing change

Questions about platform migration

The ones we are asked most often before a first conversation.

How do we know consolidating is worth it?
By doing the arithmetic before committing, which is what our Cross Platform Consultation is for. The saving depends on how much of your cost is genuinely duplication, and for apps that lean heavily on device capability the answer is often less than it looks. A migration that pays back in five years is a preference rather than a saving, and we would rather tell you that in week three of an assessment than in month nine of a migration.
Why not build the new app fresh alongside the old ones?
Because the old apps keep changing while the new one is built, and that is what these programmes consistently underestimate. Incremental embedding means there is only ever one app in the store, each moved screen is verified by real users, and a bad decision costs a screen rather than a programme. A fresh build is defensible for a small app with well-understood behaviour, and we will say so when yours is one.
Do we have to pause feature work?
No, and we would resist it. A freeze is the assumption that breaks these migrations, because the business cannot honour it for as long as the work takes. Screens are sequenced around the roadmap instead. A feature landing in a screen currently being moved takes a little longer, which is a schedule conversation rather than a stop.
We want to go the other way — one codebase back to native. Is that odd?
Not at all, and it is the right call more often than the industry admits. If the app has grown into heavy device or performance work, the shared layer stops paying for itself and starts costing, and a framework upgrade treadmill is real ongoing expense. The method is identical, run in reverse: screens move to native inside the shipping app, one at a time, each verified before the next.
Could we end up permanently half and half?
Yes, and it is a legitimate destination rather than an unfinished migration — provided it is deliberate and the boundary is documented. Plenty of good apps share the screens that change often and keep the deeply platform-specific parts native. What causes trouble is arriving there by accident, with nobody able to say why any given screen is on the side it is on.
How long does this take?
It depends on how many screens there are and how much of the behaviour is undocumented, and any number quoted before the assessment would be invented. What is scoped and dated at the end of the assessment is the first screen. Because the work is incremental and the roadmap keeps moving, a longer timeline costs you far less here than it would on a parallel rewrite.

Two codebases that should be one, or the reverse?

Tell us what you run today and which way you are leaning. We will tell you what the sequence should be.

Strictly necessaryEssential for the site to function: page navigation, security, session management, and remembering the cookie choices you make here.
Always on
FunctionalRemembers choices you make, such as language, region or display preferences, so the site opens the way you left it.
Performance and analyticsPerformance and analytics cookies show us how the Website is used: which pages are visited, how long is spent on them, where visitors came from, and what errors occur. They are set by Google Analytics and by HubSpot, whose cookies also link the pages you viewed to any enquiry you later send us.
Marketing and targetingTracks browsing activity to measure advertising and show relevant ads. We set none of these today, and will not without your opt-in.