Mobile App Migration from Xamarin to .NET MAUI
Microsoft ended Xamarin.iOS and Xamarin.Android support in May 2024. Xamarin.Forms received extended support until end of 2024. This means: no security updates, no new iOS and Android SDK version support, no bug fixes. Xamarin app — accumulating technical debt with specific end date.
.NET MAUI — official Xamarin.Forms successor. Architecturally it's evolution, not revolution. But «just update NuGet packages» won't work.
What breaks during migration
Project structure. In Xamarin.Forms three projects: common PCL/Shared + iOS head project + Android head project. In MAUI — single multi-target project: one .csproj with <TargetFrameworks>net8.0-ios;net8.0-android</TargetFrameworks>. Native resources (icons, fonts, Assets) moved to Resources/ in root of single project. Entire AppDelegate.cs, MainActivity.cs structure rebuilt.
Namespaces and API. Xamarin.Forms → Microsoft.Maui. This concerns every using statement in project. Some classes renamed: Device.BeginInvokeOnMainThread → MainThread.BeginInvokeOnMainThread, Application.Current.MainPage → Application.Current?.Windows[0].Page. Renderers replaced by Handlers — fundamentally different custom native control customization model.
Renderers → Handlers. Most painful. In Xamarin.Forms custom renderer for Entry — class inheriting EntryRenderer, overriding OnElementChanged. In MAUI Handler — property mapping via PropertyMapper and CommandMapper. Each custom renderer must be rewritten. If project has 5–10 custom renderers — serious work volume.
Dependencies and plugins. Some Xamarin plugins (especially from Xamarin.Essentials, now built into MAUI) simply disappeared or got renamed. Third-party plugins — check NuGet compatibility with net8.0-ios / net8.0-android. Plugins not updated to MAUI must be replaced with alternatives or written custom.
How we conduct migration
Dependency audit — first and most important step. Collect complete NuGet package list, check each for MAUI compatibility. For Xamarin.Essentials dependencies — good news: most APIs built into MAUI natively. For custom renderers make list with effort estimation for rewriting to Handlers.
Upgrade Assistant. Microsoft released dotnet-maui-check and .NET Upgrade Assistant with Xamarin → MAUI support. Tool does part mechanical work: updates .csproj, changes target frameworks, moves resources. But this ~30–40% of work. Rest — manual fixing.
Shell navigation. If project used Xamarin.Forms Shell — good news: MAUI Shell conceptually compatible. AppShell.xaml with <TabBar>, <FlyoutItem>, route registration via Routing.RegisterRoute — transfers with minimal changes.
Dependency Injection. In Xamarin.Forms DI wasn't built-in — used Autofac, DryIoc, TinyIoC. MAUI has built-in MauiAppBuilder with Microsoft.Extensions.DependencyInjection. This standard .NET DI, well-known to ASP.NET developers. Service registration transfers to MauiProgram.cs.
Testing. MAUI supports xUnit and NUnit for unit tests. For UI testing — Appium with dotnet-appium-driver or MAUI UI Testing compatible approaches. Business logic test coverage before migration — insurance against regressions.
After migration mandatory: manual testing on physical iOS and Android devices (simulator insufficient for native behavior check), run through TestFlight and Firebase App Distribution before release.
Timelines
| Project size | Custom renderers | Estimate |
|---|---|---|
| Up to 20 screens | None / 1–3 | 3–5 weeks |
| 20–50 screens | 3–10 | 6–10 weeks |
| 50+ screens | 10+ | 12+ weeks |
Cost calculated after project audit: .csproj analysis, NuGet dependency list and custom renderer count.







