Skip to content
Ende Sun
Back to blog

Engineering

Migrating a mobile app from Xamarin to .NET MAUI

2 min read

Migrating a mobile app from Xamarin to .NET MAUI

Context

Xamarin reached its end of support date, which meant the Osunasport mobile app had a clock running: staying on it would mean an unsupported framework, no further security or tooling updates and eventually incompatibility with new OS versions. .NET MAUI, as Microsoft's official successor, was the obvious target — it reuses most of the .NET/C# knowledge and libraries already in use, instead of forcing a jump to a completely different stack like Flutter or React Native.

The migration process

Rather than treating this as a simple "find and replace the framework" task, the migration touched the whole app:

  • Project structure: MAUI collapses the old per-platform Xamarin.Forms projects (iOS, Android, UWP) into a single shared project with platform-specific folders, which meant reorganising how platform code and resources were laid out.
  • Navigation and lifecycle: MAUI's navigation and app-lifecycle APIs differ enough from Xamarin.Forms that most of the app's navigation flow needed to be reviewed, not just recompiled.
  • Third-party dependencies: several Xamarin-only libraries had no direct MAUI equivalent and were replaced, or wrapped in custom platform handlers where no replacement existed.
  • UI/UX redesign: since most of the view layer had to be touched anyway, the migration doubled as an opportunity to redesign the app's frontend and improve its overall UI/UX rather than just porting the old screens as-is.

Once the app was stable on .NET MAUI, a second, smaller migration followed: updating from .NET 9 to .NET 10 once MAUI's tooling and third-party packages had caught up with that runtime.

Key differences found

  • Single-project structure vs. multiple per-platform projects changes how resources, fonts and platform-specific code are organised and referenced.
  • Some Xamarin.Forms custom renderers do not map 1:1 to MAUI handlers, so visual behaviour needed re-testing on both iOS and Android rather than assumed to carry over.
  • Build and packaging tooling differs enough that CI/CD pipelines needed updating alongside the app code itself.

Result

The app now runs on .NET MAUI / .NET 10, actively maintained, with a refreshed UI/UX, developed and maintained end to end by a single engineer alongside the platform's backend and architecture work.