Mobile

Xamarin → .NET MAUI migration playbook

Microsoft retired Xamarin in May 2024. .NET MAUI is the supported successor. Here’s the playbook we use on real migrations — what ports cleanly, what doesn’t, and where teams underestimate the work.

Published: April 30, 2026 · 11 min read

Microsoft ended support for Xamarin and Xamarin.Forms on May 1, 2024. The supported path forward is .NET MAUI (Multi-platform App UI), which is — broadly — Xamarin.Forms’ architectural successor with a unified .NET runtime and a single project structure. The marketing pitch is "easy migration." The reality is more nuanced. After several real migrations, here’s the playbook we use.

What “migrate” actually means

The first decision is honest scope. There are three possible projects sitting on top of an existing Xamarin.Forms codebase, and they look almost identical from the outside:

  • Mechanical port. Convert project files, swap namespaces, update binding syntax, ship. Best case: 2–4 weeks for a medium-sized app.
  • Port + cleanup. Same as above, plus retire the bits you knew were rough (custom renderers that should now be MAUI handlers, bespoke navigation that should now be Shell, async code that’s been creaking). 6–10 weeks.
  • Migration as rewrite. The codebase has accumulated 5+ years of patches, the original architect left, and the testing story is "we click through it manually before each release." MAUI is your excuse to ship a sustainable codebase. 12–24 weeks.

The mistake we see most often is assuming the project is the first kind when it’s actually the third. Discovery sprints exist for a reason.

What ports cleanly

  • XAML pages with stock controls. If your views are mostly Label, Button, Entry, ListView, etc., the XAML upgrades cleanly. Property names changed in a few places (FormattedText → FormattedString hierarchy is the same; some attached-property paths moved). The .NET Upgrade Assistant catches most of these.
  • ViewModels and services. Pure C# — your business logic, MVVM bindings, and DI registration generally come over without changes.
  • HttpClient calls and JSON serialization. No change. (If you’re still on Newtonsoft.Json, this is a fine moment to consider System.Text.Json — but that’s a separate project.)

What doesn’t port cleanly

  • Custom renderers. Xamarin’s renderer model was replaced by MAUI handlers. The concept is similar but the API surface is different and the lifecycle is different. Plan to rewrite each renderer rather than expect a one-line swap.
  • Effects. Same story — usually rebuilt as platform-specific handler customization.
  • Third-party UI controls. Whether it ports depends on the vendor. Telerik and Syncfusion shipped MAUI versions; smaller vendors often didn’t. Inventory your dependencies up-front.
  • Push notification setup. The native iOS/Android setup has shifted (especially with Firebase iOS SDK changes). Don’t assume your existing push code "just works."
  • Splash screens and app icons. MAUI has a unified resource model (MauiSplashScreen, MauiIcon) — much better, but a one-time conversion that catches teams off guard.

Architecture decisions to make early

Shell vs. NavigationPage

If your Xamarin app uses NavigationPage everywhere, you can keep that pattern in MAUI — but Shell is the recommended default for new apps and gives you a lot for free (URL-based routing, flyout, search). For most apps we’ve migrated, the right call is "stay on NavigationPage for v1, plan a Shell move for v2." Mixing them is messy.

Single project vs. head projects

MAUI’s single-project structure (one .csproj for iOS+Android+Windows+macOS) is the new default. Xamarin used separate head projects per platform. The conversion is mostly mechanical, but if you have platform-specific code that lived in the head projects, you’ll need to relocate it under Platforms/ folders. Teams underestimate this when they have a lot of native AppDelegate or MainActivity customization.

iOS minimum version

MAUI’s minimum iOS varies by .NET version and app type — check the current Microsoft supported-platforms matrix before you commit (recent .NET MAUI / MAUI Blazor releases have moved minimums to iOS 12.2 and iOS 16.4 respectively, and that floor keeps rising). If your Xamarin app supported older iOS versions because some customer base needed it, you’ll have a real conversation about cutting that support during migration.

Performance and startup

MAUI’s startup is generally faster than Xamarin.Forms, especially on iOS. But there’s a real win to be had with proper AOT compilation on iOS and the new $(MtouchInterpreter) options. Don’t accept the default; profile and tune. We’ve seen 30–50% startup improvements just from compile-flag tuning that nobody bothered with.

Testing during migration

If your Xamarin app has thin or no automated tests, that’s the bigger problem you’re going to surface. MAUI doesn’t have a testing story dramatically better than Xamarin’s. We use:

  • xUnit/NUnit for ViewModel and service tests (these port unchanged)
  • Appium or MAUI’s preview Hot Reload-driven UI testing for end-to-end
  • Manual QA on a real device matrix during the migration cutover — Calvin’s rule of thumb: at least one device per supported OS major version

Cutover strategy

For consumer apps you’ll publish a single MAUI build that replaces the Xamarin one in the stores. For enterprise/B2B apps with a known device fleet (sales-rep apps, warehouse tools), we’ve done parallel TestFlight / internal-track rollouts: keep the Xamarin app installed while a small pilot group exercises the MAUI version. Found a bug? Patch in MAUI without disrupting production users on the stable Xamarin build.

The hidden cost: third-party dependencies

The thing that breaks budgets is the long tail of third-party libraries you forgot you used. Xamarin had 10+ years of plugin ecosystem; not all of it has MAUI-compatible successors. Before you sign a fixed-bid migration, audit every NuGet reference. Anything that hasn’t been updated since 2022 is a red flag.

The takeaway

For most apps the migration is real work, not a one-week refactor — somewhere between a port and a partial rewrite. The good news: once you’re on MAUI, you’re on a supported, actively-developed platform with a future. The bad news: nobody’s shipping new Xamarin work, so even if your app is "fine," the talent pool for maintaining it shrinks every quarter.

If you have a Xamarin app you’re trying to size for migration, drop us a note. We’ll do a real audit before quoting — that’s how we avoid the “mechanical port that turned into a rewrite” trap.

Free Consultation

Have a real project this article touches?

20+ years building B2B systems. We’ll tell you honestly whether we’re the right hands for it.

877.609.9029
Start a Conversation