A field-service company, which we'll call RouteLine, had a two-line bug fix ready for its iPhone app in late April 2026. The developer finished it before lunch. By the afternoon, App Store Connect had refused the upload, and no human reviewer had even looked at it.
The code was fine. The problem was the tool that built it. Starting April 28, 2026, Apple only accepts apps built with Xcode 26 and the iOS 26 SDK (the SDK is the kit of Apple code your app compiles against). RouteLine's app was written in Xamarin.Forms, and Xamarin's final supported toolchain stops at Xcode 15. Microsoft ended Xamarin support on May 1, 2024, and the rest of the mobile world kept moving without it.
Stories like this are why teams are revisiting Xamarin app development decisions made years ago. The app still runs on customers' phones, but it can't be updated through the official stores. The question has shifted from "should we move?" to "where, and how do we avoid breaking things?"
Key takeaways
• A Xamarin app published on the App Store or Google Play can no longer ship updates, because both stores now require toolchains Xamarin never supported.
• .NET MAUI is Microsoft's direct successor to Xamarin.Forms, and most of your C# business code carries over with it.
• Flutter is a reasonable choice when you plan to redesign the interface anyway, but it means rewriting the app in a different language.
• .NET 11, due at .NET Conf on November 10 to 13, 2026, replaces the engine that runs MAUI apps on phones. Test against it before it ships.
• The riskiest parts of a migration are usually invisible: saved user data, old plugins and release-only build settings.
A quick refresher on what Xamarin actually did
Xamarin let C# developers write iPhone and Android apps without learning Swift or Java. Microsoft bought it in 2016. For most of the next decade, it was the default way for companies that already used Microsoft technology to build cross-platform mobile apps, meaning apps that run on more than one operating system from mostly the same code.
It came in two flavours, and the difference matters for your migration.
Xamarin.iOS and Xamarin.Android (often called "Xamarin Native") let you share business logic, like pricing rules, syncing and login, while you still built each platform's screens separately in C#.
Xamarin.Forms went one step further. You described each screen once, usually in XAML (a markup language that looks a bit like HTML and lays out buttons, lists and text), and Forms turned it into real iPhone and Android controls when the app ran.
Underneath both sat Mono, an open-source .NET runtime. A runtime is the engine that runs your compiled code on the device, and it matters again when we reach .NET 11.
The end date, and why it only started hurting recently
When support ended in May 2024, plenty of teams shrugged. Their apps kept working. The pain arrived later, from Apple and Google.
Both stores raise their minimum build requirements every year. Xamarin's last targets were Android API level 34 (Android 14) and Xcode 15, and every deadline since has moved past them.
That August 2026 line is the one founders tend to miss. Your old app doesn't get deleted. Instead, Google Play quietly stops showing it to new users whose phones run a newer Android version than the app targets.
There's also a data gap that catches larger companies. Many businesses have internal Xamarin apps that never touched a public store. They're installed through MDM, short for mobile device management, the software IT teams use to push apps to company phones. Those apps skip store rules entirely, so they look safe. They aren't. They still run on an unpatched framework, and each new iOS or Android release is a fresh chance for something like camera access or background location to stop behaving.
Pro tip
Before you plan anything, build an inventory. List every Xamarin app your company owns, including internal ones, with its last successful build date, who owns it and which store or MDM tool distributes it. Teams that skip this step often find a forgotten app only when it breaks.
What .NET MAUI changes under the hood
The name stands for .NET Multi-platform App UI. Think of it as Xamarin.Forms rebuilt on modern .NET. The C# and XAML look familiar, and a lot of existing code moves across with renaming and cleanup rather than a rewrite.
The changes that matter most in day-to-day work are these.
One project instead of many. A Xamarin.Forms solution usually had a shared project plus a separate project for each platform. MAUI puts everything in a single project, with platform-specific code in clearly named folders.
Handlers replace renderers. In Xamarin.Forms, a renderer was the piece of code that turned a shared "Button" into a real iPhone or Android button. Customising one was heavy work. MAUI uses lighter handlers with "mappers", small rules that say "when this property changes, do this on the native control". Changing how every text box looks on Android can take a few lines instead of a whole class.
Desktop comes along for free. The same project can target Windows and macOS (through Mac Catalyst, Apple's way of running iPad-style apps on a Mac), which suits office teams wanting one internal tool on laptops and phones.
It rides the normal .NET release train. .NET MAUI gets a new major version every November with the rest of .NET, which brings current C# features, faster libraries and security fixes in one bundle.
The .NET 10 release, which shipped in November 2025, pushed things along in a few specific ways. ListView, the list control most Xamarin apps were built around, is now marked as deprecated, and Microsoft points everyone to CollectionView instead. The newer, faster CollectionView handlers on iOS, which were optional in .NET 9, became the default. There's also a XAML source generator, which converts your screen layouts into regular C# code while the app builds rather than while it runs. That means fewer runtime surprises.
The numbers, and how far to trust them
Market data here is thin, so it helps to know what each number measures.
• In the 2024 Stack Overflow Developer Survey, 9.4% of professional developers said they used Flutter, 9% used React Native, and 3.4% used .NET MAUI.
• App intelligence firm Appfigures found React Native inside 1,350 of the top 10,000 non-game iOS apps in December 2025, compared with 1,184 for Flutter.
• Appfigures data from January to October 2024 detected Flutter in about 11% of newly released apps, against roughly 7% for React Native.
These figures seem to contradict each other. Flutter leads in surveys and new releases, while React Native shows up in more of the most successful apps. Both can be true. Surveys ask people what they used last year. Store scans count apps that shipped.
Then there's the gap nobody can fill. No public dataset reliably counts MAUI apps, partly because so many of them are internal business tools that never appear in store rankings. A 3.4% survey share tells you MAUI has a smaller community. It doesn't tell you how many hospital, logistics or banking apps quietly run on it.
Use these numbers for hiring and ecosystem planning. A bigger community means more tutorials, packages and job candidates. When people frame the choice as Xamarin vs Flutter, the survey gap is often the first thing they point to. That's fair, but it says little about whether a framework suits the app you already have.
One more conflicting signal deserves a mention. .NET 10 is a long-term support release, which in Microsoft's terms means three years of support. MAUI follows its own policy, though. A major version of .NET MAUI is guaranteed support for at least six months after the next major version ships. So MAUI 10 is covered until roughly May 2027, even though .NET 10 itself runs to late 2028. In practice, a MAUI app needs a yearly upgrade, and budgets should treat that as routine maintenance rather than a surprise project.
Xamarin, MAUI and Flutter side by side
Why so many teams end up asking about Xamarin vs Flutter
When a company learns it has to move off Xamarin anyway, someone usually asks whether this is the moment to switch camps entirely. That's when the Xamarin vs Flutter conversation starts.
The biggest technical difference is how the two draw your screens. MAUI hands the job to the operating system. A MAUI button on an iPhone is a real iPhone button, so it behaves the way iPhone users expect, and accessibility features like screen readers work with it naturally. Flutter paints everything itself with a rendering engine called Impeller, a bit like a game engine drawing its own menus. Your app looks identical on every phone, down to the pixel.
When Apple introduced its new Liquid Glass design in iOS 26, apps built with the iOS 26 SDK picked up the new look on native controls by default. For a MAUI app, that's free modernisation, but it can also move a button or change a colour your designer signed off on, so someone has to test for it. A Flutter app doesn't change at all until Flutter's own widgets are updated, which is predictable but can leave the app looking dated next to its neighbours.
A Xamarin.Forms app moving to MAUI keeps its C# models, validation rules, API clients and often most of its view models. Moving to Flutter means rewriting all of it in Dart. For a 10-screen app with a fresh design planned, that rewrite might be perfectly acceptable. For a 120-screen field operations app with years of edge-case fixes baked in, it rarely is, because those fixes are often undocumented and live only in the code.
Team skills tip the scales too. A C# team can be productive in MAUI in weeks. Learning Dart and Flutter's widget style takes longer, even for good developers.
Flutter wins clearly in a few situations: a consumer app where brand design matters more than native feel, a team that wants one codebase for web as well as mobile, or a startup hiring fresh and wanting the largest possible talent pool. React Native deserves a look in the same situations if your team already knows JavaScript. C# teams wanting Flutter-style pixel control can also look at Uno Platform and Avalonia.
Where migrations quietly break
The official upgrade guides cover the obvious steps well. The problems that delay launches tend to sit in less obvious places.
Saved data that seems to vanish
This one hurts users directly. MAUI stores simple settings (Preferences) and secrets like login tokens (SecureStorage) in different locations from Xamarin.Essentials, the helper library most Xamarin apps used. If you ship the MAUI version without a migration step, it opens on a customer's phone, looks for saved values in the new place, finds nothing and behaves like a fresh install. Customers get logged out and lose their settings.
Microsoft's documentation includes helper code for reading the old Xamarin.Essentials locations. The safe pattern is to check for old values on first launch, copy them across, confirm the copy worked and only then delete the old entries.
The testing mistake to avoid is only testing clean installs. Install the old Xamarin build from the store on a real device, sign in, change a few settings, then install the new MAUI build on top. That upgrade path is the one your real users take.
Custom renderers
Every custom renderer in a Xamarin.Forms app needs to become a handler or a mapper change, or be kept temporarily through MAUI's compatibility layer. Count them before you estimate anything. An app with three custom renderers and one with forty are very different projects even if they have the same number of screens.
Plugins that never made the trip
Many Xamarin apps depend on small community packages for things like barcode scanning, charts or payment screens. Some of those packages were ported to MAUI, some were replaced by other libraries, and some were simply abandoned. Check each dependency on NuGet (the .NET package library) for builds that support modern .NET. For anything missing, decide early whether to find a replacement, write your own or wrap the native Android and iOS library directly.
Android's 16 KB page size rule
Since November 1, 2025, Google Play has required apps targeting Android 15 or later to support devices that use 16 KB memory pages. A memory page is the chunk size the phone's operating system uses to manage memory. Your C# code isn't affected, but any bundled native library (compiled C or C++ code, often hidden inside a third-party package) must be rebuilt for the new alignment. An old imaging or encryption library can fail this check and block the release, so scan your final Android package before the week of submission.
Release builds that behave differently from debug builds
MAUI release builds use trimming, which removes code the build tools think you don't use, to keep the app small. Code that looks up classes by name while the app is running, a technique called reflection, can confuse the trimmer. Older JSON libraries and some dependency injection setups rely on it. The result is an app that works perfectly on the developer's machine in debug mode and crashes on a tester's phone in release mode. Test release builds on real hardware from the first sprint, not the last.
Old habits in platform code
Xamarin.Forms apps often used DependencyService to call platform-specific code. MAUI prefers standard dependency injection, where services are registered once at startup and handed to the classes that need them. The move is mostly mechanical but touches many files, so schedule it as its own task.
Pro tip
Migrate in thin vertical slices. Move one complete feature, say login plus the home screen, all the way to a release build on real devices before touching the next one. It surfaces trimming, storage and plugin problems in week two instead of week twelve.
How MAUI behaves under pressure and at scale
Small demo apps hide most performance questions. Real behaviour shows up with long lists, live data and older phones.
Long lists and live updates
Most business apps are lists at heart. CollectionView only creates the rows that are visible on screen and recycles them as the user scrolls, a technique called virtualisation. It handles thousands of items well as long as each row stays simple. Deeply nested layouts inside each row, or rows with very different heights, are what usually cause stutter.
Live data adds another layer. Say a dispatch app receives location updates for 200 drivers every few seconds. Each change to the list's data source tells the screen to redraw, and all screen changes must happen on the main UI thread (the single line of work that handles taps and drawing). If updates arrive faster than the phone can draw them, taps start to lag and the app feels frozen even though nothing has crashed.
The fix is a real-time decision you build into the app: collect incoming updates in the background, then apply them to the screen in batches a few times per second. A half-second delay is invisible to a dispatcher; a frozen screen is not. The same thinking applies when signals conflict, for example when a driver's phone reports a location that's older than the one already on screen. The app needs a rule, such as "always keep the newest timestamp", written down and tested, or the screen will jump backwards at random.
Memory over a long shift
A common MAUI problem is pages that stay in memory after the user navigates away, usually because an event subscription or a static reference still points to them. Each visit adds a little more memory until the operating system kills the app. Unsubscribing from events when pages close catches most of it. From .NET 11, the standard .NET diagnostic tools such as dotnet-counters work directly against apps on the device, which makes this much easier to track down.
Startup time and app size
Large apps with hundreds of XAML files used to pay a startup cost while those layouts were read at launch. The XAML source generator in .NET 10 moves that work to build time. Ahead-of-time compilation, where code is converted to machine code before it reaches the phone, can speed up startup further at the cost of a bigger download. Measure on the oldest phone your customers actually use.
The build pipeline at team scale
iOS builds need a Mac with a current Xcode, and Xcode 26 itself needs a recent version of macOS. Teams that pin their build machines to old images discover this on submission day. Schedule the toolchain upgrade for the same months each year so it stops being an emergency.
Making the call: a decision path for owners and teams
For founders and business owners, the choice comes down to a few plain questions, taken in order.
1. Is the app in a public store? If yes, you're already blocked from shipping updates, and the timeline is urgent. If it's internal only, you have more time, but not unlimited time.
2. Is it Xamarin.Forms or Xamarin Native? Forms apps move to MAUI. Native apps move to .NET for Android and .NET for iOS, which keep the same per-platform approach on modern .NET.
3. How much custom native code is there? Count custom renderers, platform services and native libraries. This number drives cost far more than screen count.
4. Is a redesign already planned? If the whole interface is being redesigned in the next year, the cost gap between migrating and rewriting in Flutter shrinks a lot.
5. What does your team know? C# teams move fastest to MAUI. Teams that are hiring from scratch have more freedom.
Agencies building cross-platform mobile apps for clients see a clear pattern here. The Xamarin vs Flutter debate gets heated in meetings, but the spreadsheet usually settles it: when most of the value lives in tested C# logic, MAUI wins on cost, and when most of the value is in a new user experience, Flutter becomes a serious contender.
What's next: .NET 11 and the end of Mono on phones
Since the Xamarin days, MAUI apps on Android and iOS have run on Mono. In May 2026, Microsoft announced that CoreCLR, the runtime already behind ASP.NET Core web servers, Azure services and desktop .NET apps, would become the default for MAUI on Android, iOS and Mac Catalyst starting with .NET 11 Preview 4. By Preview 6 in July, CoreCLR had become the only option for those platforms, with no way to switch back to Mono.
Microsoft's performance guidance so far is modest. iOS and Mac Catalyst apps are generally faster than on Mono, and Android is within about 10% of Mono on startup time and app size. The bigger benefits are about consistency. Your phone app now runs on the same engine as your backend, so bugs, tools and performance behaviour are shared. Developers also get dotnet watch (automatic rebuilds as you edit) for Android and iOS, plus early groundwork for NativeAOT on Android, which compiles the whole app to machine code ahead of time.
Most apps won't need code changes. Apps that rely on Mono-specific behaviour, older native bindings or unusual reflection tricks might. The final release is expected at .NET Conf on November 10 to 13, 2026, and the six-month support window means MAUI 10 apps should plan to move to 11 by around May 2027.
Pro tip
Create a branch today that builds your app against the latest .NET 11 release candidate. Run it on your oldest supported Android phone and your oldest iPhone, and compare startup time and memory against your current build. A week of testing now is cheaper than a rushed upgrade next spring.
For anyone still on Xamarin, there's a small irony in all this. The Mono runtime that made Xamarin app development possible back in 2011 is now leaving MAUI mobile apps entirely. Moving straight to .NET 10 or 11 means jumping across more than a decade of runtime changes, which is one more reason to test early and on real devices.
Conclusion
If you run a Xamarin app today, the deadline has already passed in the ways that count. Both stores now require builds Xamarin can't produce, and Google's August 2026 rule means older apps are losing visibility with new users.
For most Xamarin.Forms apps, MAUI is the practical next step. It keeps your C# code and your team's skills, meets current store rules and is heading onto a stronger runtime with .NET 11. Flutter is a strong alternative when a redesign is already on the table or when you're starting fresh with a team open to Dart.
Whichever way you go, plan carefully around what customers feel: saved logins, plugins behind important features and release builds on real phones. Build an inventory, migrate one feature first and schedule the yearly upgrade. Xamarin app development served a lot of businesses well for a long time, and the teams that treat this move as a planned project instead of an emergency are the ones whose users barely notice it happened.


