{
  "id": 11740353,
  "title": "The Pitfalls of Migrating from Xamarin.Forms to .NET MAUI",
  "url": "https://urgent.news/2026/10/03/the-pitfalls-of-migrating-from-xamarin-forms-to-net-maui",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-03T18:13:21.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/geluvac/the-pitfalls-of-migrating-from-xamarinforms-to-net-maui-17o2"
  },
  "original_language": "en",
  "account": "The transition from Xamarin.Forms to .NET MAUI is not as straightforward as changing a namespace. The migration process involves several challenges, particularly around custom renderers, navigation, and plugins that are no longer maintained. Microsoft ended support for Xamarin in May 2024, which adds pressure as Apple and Google raise minimum SDK requirements for new app submissions.\n\nFrom a technical standpoint, the upgrade process is relatively simple. The project moves to a single-project format, Xamarin.Forms becomes Microsoft.Maui.Controls, and Xamarin.Essentials is now built directly into the framework. Automated upgrade tools and AI assistants can handle this aspect quite well. However, the difficulties arise when the system cannot understand why a custom renderer was implemented, how the code assumed the order of page loading, or which hidden behaviors an old plugin provided.\n\nOne major conceptual shift in MAUI is that it no longer customizes controls through inheritance like Xamarin.Forms did, but through mappers: dictionaries that link each property of a cross-platform control to the native code that applies it. Customizing an Entry control to remove its underline on Android, for instance, would traditionally require writing an entire renderer. In MAUI, this is achieved by adding an entry to the existing mapper, typically in MauiProgram.cs. This global mapping approach means that any change made to a mapper will apply to every entry in the app, which can lead to unintended consequences if not handled carefully.\n\nAnother issue is that the OnElementChanged method, which was used in Xamarin.Forms to mix the creation of the native control, event subscriptions, and cleanup, has no direct equivalent in MAUI. This separation into CreatePlatformView, ConnectHandler, and DisconnectHandler can lead to memory leaks or events firing twice if not implemented correctly. MAUI also has specific requirements regarding the way custom handlers are implemented, with certain methods not being optional.\n\nWhen it comes to shell and navigation, MAUI recommends using Shell as the recommended approach, replacing older pages like NavigationPage, TabbedPage, and MasterDetailPage. However, this change involves more than just syntax; it impacts how pages are structured and navigated. Shell has specific rules about what types of pages it accepts and how routes and parameters are handled. For instance, pages not appearing in the Shell visual hierarchy must be registered explicitly, and route parameters need to be managed differently than in Xamarin.Forms.\n\nOne of the most time-consuming aspects of the migration is dealing with custom renderers. While MAUI allows old renderers to be registered through AddCompatibilityRenderer, this approach is considered technical debt. It may help in getting the app running quickly but lacks the optimizations of the new pipeline. The recommendation is to use compatibility renderers only as an intermediate step and to clear each remaining renderer through a clear ticket system.\n\nAnother pitfall is the change in the type of native control used by handlers. In Xamarin.Forms, handlers often cast to specific native classes. In MAUI, the handler.PlatformView may be a MAUI-derived class rather than the original native class, which can result in an InvalidCastException if not handled properly.\n\nShell and navigation changes also impact the lifecycle of pages. With ContentTemplate, Shell creates pages the first time they are shown, not when the app starts. This differs from Xamarin.Forms where pages are loaded early in the app's lifecycle. Code that relies on view models being available at app startup may miss certain events in the new system. Additionally, pages within tabs can have OnAppearing called every time the tab is switched, rather than only once. This requires developers to ensure their data-loading logic is idempotent to avoid redundant operations.",
  "summary": "Why the migration is not a simple upgrade On paper, migrating from Xamarin.Forms to .NET MAUI looks like a namespace change. In practice, the time goes into three areas: custom renderers, navigation, and plugins that are no longer maintained. Microsoft's support for Xamarin ended in May 2024, and the apps still on it are getting harder to publish as Apple and Google raise their minimum SDK…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}