All Articles
Reading Time
14 min read
Published
2025-11-11
Word Count
3,446words

Grab a coffee — this one is a deep dive!

.NET MAUI 10: XAML Source Generator and SafeArea Guide

Summary

We break down .NET MAUI 10's XAML source generator and expanded SafeAreaEdges API straight from official Microsoft docs, plus a migration checklist for Xamarin.Forms teams.

  • .NET MAUI 10 reached GA alongside .NET 10 on November 11, 2025, and carries LTS status.
  • The XAML source generator turns on via the MauiXamlInflator=SourceGen property and compiles XAML into type-safe code at build time.
  • The SafeAreaEdges API expanded (None/SoftInput/Container/Default/All) and works on Layout, ContentView, ContentPage, Border, and ScrollView.
  • ListView, Cell-based controls, old animation APIs, and MessagingCenter are deprecated; migrate to CollectionView and WeakReferenceMessenger.
.NET MAUI 10: XAML Source Generator and SafeArea Guide

.NET MAUI 10 reached general availability (GA) on November 11, 2025 alongside .NET 10, bringing three major changes for developers targeting iOS, Android, Windows, and macOS from a single codebase: a new XAML source generator that runs at compile time, an expanded SafeAreaEdges API, and .NET Aspire service template integration. In this post I walk through the .NET MAUI 10 XAML source generator and SafeArea duo straight from the official Microsoft documentation, and distill a practical checklist for teams migrating from Xamarin.Forms or older MAUI projects.

💡 Pro Tip: Before setting MauiXamlInflator to SourceGen, remove any manual source-generation enablement code left over from before RC1 — the documentation says this code can now be removed.

Table of Contents

.NET MAUI 10: What Changed, in One Table

.NET MAUI 10 shipped as GA as part of .NET 10 and carries LTS (Long-Term Support) status. The table below summarizes the timeline and support details that directly concern the MAUI ecosystem, straight from official sources.

GA and Support Timeline

Field
Value
Source
GA date
November 11, 2025
Microsoft .NET Blog (devblogs)
Release type
LTS (Long-Term Support)
Microsoft .NET Blog
LTS support end (overall .NET 10)
November 10, 2028
Microsoft .NET Blog
.NET MAUI 10 support end
May 11, 2027
.NET MAUI support policy page
MAUI minor update plan
Not currently planned, only servicing patches
.NET support policy page

The practical takeaway from this table: the MAUI workload's support window and the .NET runtime's LTS window follow separate policies. .NET MAUI 10's support ends on May 11, 2027, while the .NET 10 runtime's LTS runs through November 10, 2028. The support policy page states the rule plainly: "A major version of .NET MAUI receives support for a minimum of 6 months after a successor (the next major release) ships." So plan around the workload's own timeline, not the runtime's.

Why It Matters Now

If you're still running a project on Xamarin.Forms or an older version of .NET MAUI, .NET MAUI 10's LTS status forces an important decision: MAUI 10's support window closes on May 11, 2027, so the cost of delaying migration grows every month. Especially if you have a large codebase still leaning heavily on deprecated controls like ListView, planning the migration in small steps (first cleaning up deprecated APIs, then moving to the source generator) is less risky than a single "big bang" migration. The rest of this post follows that same order: first the compile-time tooling (source generator), then runtime behavior (SafeArea), then the migration checklist.

XAML Source Generator: Compile-Time Type Safety

One of the most concrete developer-experience changes in .NET MAUI 10 is that XAML files can now be processed at compile time. The official documentation summarizes it this way: the source generator "improves build performance and enables better tooling support" and "creates strongly-typed code for your XAML files at compile time." In other words, instead of "inflating" XAML at runtime via reflection, the compiler generates type-safe C# code for you directly.

Turning this on in your project takes a single line:

xml
1<PropertyGroup>
2 <MauiXamlInflator>SourceGen</MauiXamlInflator>
3</PropertyGroup>

The generated types are marked with a [Generated] attribute for tooling integration and the debugging experience — making it easier for the IDE and debugger to distinguish hand-written code from generated code.

Cleanup From Pre-RC1 Code

Watch out if your project started before .NET MAUI 10's RC1 release: the documentation explicitly says "Before RC1 enabling source generation was different... Any other code you have implemented to enable source generation can now be removed." So if you have old, hand-written enablement code, you can replace it with the MauiXamlInflator line and clean it up — the documentation says this code can now be removed.

Note: the documentation doesn't share a concrete performance percentage (in ms or %) — only a qualitative "improves build performance" statement. If you want to measure it in your own project, you can compare build times across two separate clean builds with SourceGen on and off.

Comparison With the Old Runtime Inflator

The table below summarizes the behavioral difference between the two approaches as described in the documentation. It's not a numeric measurement, just the official text's qualitative comparison.

Feature
Runtime Inflator (old default)
Source Generator (SourceGen)
XAML processing time
While the app runs (via reflection)
At compile time
Type safety
Surfaces as a runtime error
Caught at compile time
Tooling support
Limited
Improved via the [Generated] attribute
Pre-RC1 manual enablement
Not needed
Old manual code must be removed

This table helps you predict which XAML errors in your project will now be caught at build time: mistakes like a wrong property name or a type mismatch no longer require running the app to surface.

SafeArea API: Screen Edges and the Keyboard

.NET MAUI 10 expanded the SafeAreaEdges API. The enum values are: None = 0, SoftInput = 1, Container = 2, Default = 4, All = int.MaxValue. The SoftInput value specifically controls how the layout handles the safe area when the keyboard opens.

xml
1<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
2 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
3 <Grid RowDefinitions="*,Auto"
4 SafeAreaEdges="Container, Container, Container, SoftInput">
5 <ScrollView Grid.Row="0">
6 <VerticalStackLayout Padding="20" Spacing="10">
7 <Label Text="Profil" FontSize="24" />
8 <Entry Placeholder="Ad" />
9 <Entry Placeholder="E-posta" />
10 </VerticalStackLayout>
11 </ScrollView>
12 
13 <Border Grid.Row="1"
14 BackgroundColor="LightGray"
15 Padding="20">
16 <HorizontalStackLayout Spacing="10">
17 <Entry Placeholder="Mesajınız" HorizontalOptions="Fill" />
18 <Button Text="Gönder" />
19 </HorizontalStackLayout>
20 </Border>
21 </Grid>
22</ContentPage>

Two details are worth noting. First, the documentation says SoftInput doesn't work directly on ScrollView: "SoftInput doesn't work directly on ScrollView because ScrollView manages its own content insets." The fix is in the same place: wrap the ScrollView in a Grid or VerticalStackLayout and put SafeAreaEdges on the wrapping container instead. Second, the comma-separated syntax isn't flag combination — it's a per-edge list of values; in the documentation's own terms, the example above requests Container on the top and sides, and SoftInput on the bottom.

According to the documentation, SafeAreaEdges can be used on Layout, ContentView, ContentPage, Border, and ScrollView. .NET MAUI 10 also fixes a known iOS bug: "Resolved issues with SafeArea management on iOS, including extra bottom space in ScrollView when using SafeAreaEdges" — meaning the extra bottom spacing that used to appear in ScrollViews using SafeAreaEdges on iOS has been fixed.

Which Controls Support SafeAreaEdges

  • Layout: base layout containers such as VerticalStackLayout, Grid
  • ContentView: the base class for custom user controls
  • ContentPage: the standard page type
  • Border: a bordered content container
  • ScrollView: scrollable content — a control with special behavior in keyboard scenarios (SoftInput doesn't work directly)

Default values vary by control type: None for ContentPage, Container for Layout and its derivatives, None for ContentView and Border, Default for ScrollView. On Android, this is .NET 10's breaking change: in .NET 9, ContentPage on Android behaved close to Container by default; in .NET 10, "ContentPage defaults to None (edge-to-edge), providing a more immersive experience by default." If you want to keep the .NET 9 behavior, you need to explicitly set ContentPage.SafeAreaEdges="Container".

Combined Usage Example With Border

Using SafeAreaEdges on Border is especially useful for custom components that sit near the bottom of the screen, like a bottom navigation bar:

xml
1<Border SafeAreaEdges="Container"
2 Stroke="Transparent"
3 StrokeThickness="0">
4 <Border.StrokeShape>
5 <RoundRectangle CornerRadius="16,16,0,0" />
6 </Border.StrokeShape>
7 <Grid Padding="16" ColumnDefinitions="*,*,*">
8 <Label Grid.Column="0" Text="Ana Sayfa" />
9 <Label Grid.Column="1" Text="Ara" />
10 <Label Grid.Column="2" Text="Profil" />
11 </Grid>
12</Border>

The documentation defines Container as: it respects the container's safe areas (system bars, notch) but allows content to flow under the keyboard. In other words, it keeps the Border from overlapping the home indicator area on iPhone; if you want content to stay above the keyboard when it opens, you need SoftInput instead.

.NET Aspire Service Template Integration

Another change that ships with .NET MAUI 10 is .NET Aspire support in the new project templates. The official wording: ".NET MAUI 10 includes a new project template that creates a .NET Aspire service defaults project for .NET MAUI." This makes it easier to develop the mobile/desktop app together with its backend services under a single Aspire orchestration — especially useful for MAUI apps that connect to a microservice-based backend.

In practice, this change means the following: previously, when developing a MAUI app alongside an ASP.NET Core-based backend, you had to configure the two projects (mobile client + backend) separately and hand-build common infrastructure code like service discovery, logging, and health checks. The new project template wires this "service defaults" project into the MAUI side as well, letting you monitor the health of both the mobile app and the backend services from Aspire's single dashboard. According to the documentation, wiring it up takes a single call on the MauiAppBuilder object inside the CreateMauiApp method of your MauiProgram class:

csharp
1builder.AddServiceDefaults();

The things AddServiceDefaults does are listed explicitly as well: setting up OpenTelemetry metrics and trace configuration, adding service discovery functionality, and configuring HttpClient to work with service discovery.

Migration Checklist for Xamarin.Forms and Older MAUI Projects

Several APIs were deprecated in .NET MAUI 10. If you're migrating an older Xamarin.Forms or previous MAUI version project, you can use the list below as a checklist:

  • ListView and Cell-based controls: ListView, EntryCell, ImageCell, SwitchCell, TextCell, and ViewCell are deprecated; CollectionView is recommended instead.
  • Animation APIs: older animation methods like FadeTo are deprecated, replaced by their Async-suffixed counterparts (FadeToAsync, etc.).
  • MessagingCenter: made internal in .NET 10, no longer accessible from outside the project; WeakReferenceMessenger is recommended instead.
  • CollectionView/CarouselView handlers: new handlers became the default for these two controls in .NET MAUI 10.

The animation API migration looks like this in code:

csharp
1// Before (deprecated API)
2await profileImage.FadeTo(0, 250);
3 
4// After (.NET MAUI 10)
5await profileImage.FadeToAsync(0, 250);

The MessagingCenter migration looks like this:

csharp
1// MessagingCenter is now internal - no longer accessible from outside the project
2// Use WeakReferenceMessenger from CommunityToolkit.Mvvm instead
3WeakReferenceMessenger.Default.Send(new StatusChangedMessage(newStatus));

None of these changes are at the "recommended" level — since APIs marked deprecated may be removed in the future, they absolutely belong on your migration checklist.

Deprecated (old)
Recommended (new)
Why
ListView
CollectionView
Performance and flexibility
EntryCell / TextCell / ImageCell / SwitchCell / ViewCell
DataTemplate inside CollectionView
The Cell model is being removed
FadeTo and similar animation methods
FadeToAsync and other Async-suffixed counterparts
API consistency
MessagingCenter
WeakReferenceMessenger (CommunityToolkit.Mvvm)
MessagingCenter was made internal

I'd recommend turning this table into a migration ticket by treating each row as a separate work item — the ListView to CollectionView migration in particular is a significant effort on its own, since it requires rewriting your data templates.

Diagnostics and Layout Performance Metrics

.NET MAUI 10 provides built-in diagnostics/metrics names for observing layout measurement performance. The metric names that appear in the documentation and the related GitHub pull request are:

csharp
1// .NET MAUI 10 diagnostics metric names (naming only; not a code sample)
2// maui.layout.measure_count
3// maui.layout.measure_duration (ns)
4// maui.layout.arrange_count
5// maui.layout.arrange_duration (ns)

These metrics hook into the standard .NET diagnostics infrastructure (System.Diagnostics.Metrics) via the Microsoft.Maui ActivitySource — meaning you can collect them with your existing OpenTelemetry-based monitoring tools.

These counters pay off when a screen shows unexpected slowness during layout passes: check whether maui.layout.measure_count and maui.layout.arrange_count are higher than normal. A high measure_count usually means a deeply nested Grid/StackLayout combination is being measured repeatedly, typically fixed by simplifying the layout tree.

Other Notes: Global Namespace, Secondary Toolbar, MediaPicker

  • Global XML namespace: a new xmlns named http://schemas.microsoft.com/dotnet/maui/global lets you consolidate multiple namespaces in one place.
  • Secondary toolbar items: iOS and macOS now support secondary toolbar items with a pull-down menu design, using iOS 13+ APIs.
  • Showing a modal as a popover: a platform-specific API was added for iOS and Mac Catalyst to display a modal page as a popover.
  • MediaPicker improvements: EXIF data is now handled automatically; the API supports multi-file selection and direct compression via MaximumWidth/MaximumHeight.

Each item looks small alone, but together they show .NET MAUI 10 paying increasing attention to platform-specific details (iOS toolbar design, EXIF metadata). The MaximumWidth/MaximumHeight support in MediaPicker in particular is a direct dependency-reduction opportunity for teams that previously added a manual image-compression library.

Where .NET MAUI 10 Stands Against Flutter and React Native

.NET MAUI 10's XAML source generator conceptually converges with Flutter's compile-time type-checked widget tree and the compile-time codegen steps in React Native's new architecture (Fabric/TurboModules): all three are moving toward "generate at compile time instead of reflecting/interpreting at runtime." A precise performance comparison, though, would require testing all three frameworks with the same measurement methodology; conceptual convergence alone is not a speed claim.

If you want to evaluate the cross-platform ecosystem from a wider angle, you can check out our posts on Flutter's own performance-optimization practices and where Kotlin Multiplatform and Compose Multiplatform stand in production; putting these three approaches (MAUI, KMP, Compose Multiplatform) side by side makes it much clearer which trade-off each team is accepting.

What Drives the Team's Choice

I prefer not to reduce this kind of decision to a single technical feature (such as whether it has a source generator or not). In practice, the team's existing skill set tends to decide it: if the team already knows C#/.NET backend, MAUI's learning curve stays low; if the team is closer to Dart or TypeScript, Flutter or React Native is the more natural choice. It's more accurate to read the changes covered here (source generator, SafeArea, deprecation cleanup) not as a claim of "superiority," but as a sign the ecosystem keeps maturing — all three frameworks are investing in compile-time tooling at their own pace.

FAQ

What's new in .NET MAUI 10?

.NET MAUI 10 (GA: November 11, 2025) brought built-in diagnostics/metrics support for layer performance, a compile-time XAML source generator (MauiXamlInflator=SourceGen), an expanded SafeAreaEdges API, secondary toolbar items on iOS/macOS, and .NET Aspire service template integration. ListView and related Cell types were also deprecated at the same time.

How do I enable the MAUI XAML source generator?

Add <MauiXamlInflator>SourceGen</MauiXamlInflator> inside a PropertyGroup in your project file (.csproj). If your project has manual source-generation code left over from before RC1, you need to remove that old code when adding this line.

Is ListView deprecated in MAUI?

Yes. In .NET MAUI 10, ListView, EntryCell, ImageCell, SwitchCell, TextCell, and ViewCell are deprecated; CollectionView is recommended instead.

When did MAUI 10 reach GA?

.NET MAUI 10 reached general availability alongside .NET 10 on November 11, 2025, and carries LTS status (primary source: Microsoft .NET Blog).

Should I migrate my Xamarin.Forms project directly to MAUI 10?

The more controlled path is to first move your existing project to the last servicing level of the previous MAUI version, then migrate to MAUI 10. The things specific to .NET MAUI 10 you need to clean up are ListView and Cell types, old animation methods, and MessagingCenter usage — these are marked deprecated or internal in the documentation.

Does the XAML source generator actually reduce build times?

Microsoft's official documentation only uses a qualitative statement here: "improves build performance and enables better tooling support." No concrete ms or percentage figure is shared. So I can't give you a definitive number for your own project — the only reliable method is to measure two separate clean build times on the same project with MauiXamlInflator toggled on and off.

Update (September 2026)

Since this post first published, MAUI itself hasn't seen a major feature change — the official support policy page says "Minor updates for .NET MAUI aren't planned at this time," meaning only servicing patches are coming (the latest patch listed by the support policy page: 10.0.101, September 7, 2026). On the NuGet package feed, however, you can see that a 11.0.0-rc.1 build for the .NET 11 line of Microsoft.Maui.Controls has been packaged (the NuGet flatcontainer registry shows the version tag 11.0.0-rc.1.26451.6). This is a sign that .NET 11 has entered its RC phase. On the support side, the policy page still lists .NET MAUI 10's support end date as May 11, 2027.

Conclusion

.NET MAUI 10 shifts the developer experience toward compile time with its XAML source generator and expanded SafeAreaEdges API — which also means it's conceptually converging with Flutter's compile-time approach. If you're migrating an older Xamarin.Forms or MAUI project, first check the deprecated API list (ListView, animation methods, MessagingCenter), then add the MauiXamlInflator=SourceGen line and clean up the old enablement code.

If you want to evaluate the cross-platform decision in a wider context, take a look at Flutter's 60,000-line production comparison against SwiftUI, Kotlin Multiplatform's production case study, Compose Multiplatform's Android/iOS production experience, and our post on React Native's new architecture, Fabric/TurboModules. If you're curious about Flutter-side performance-optimization practices, our Flutter performance optimization guide is also worth a look.

Sources

GOLDEN TIP

The most valuable insight in this article

This tip holds the article's most important takeaway.

Easter Egg

You found a hidden gem!

There's a hidden detail in this section. Want to uncover it?

Reader Reward

Before you move from reading this post to implementing, I put together a checklist you can quickly run through for a project migrating to .NET MAUI 10. The items below are a compilation of the sourced information covered in the post; feel free to reorder them based on your own project's needs.

Tags

#.NET MAUI#XAML#Source Generator#SafeArea#Xamarin.Forms#Cross-Platform#.NET 10
Muhittin Çamdalı

Muhittin Çamdalı

Lead Mobile Engineer

Lead Mobile Engineer with 12+ years of experience. Expert in iOS, Android and cross-platform architectures with Swift, SwiftUI, Kotlin and Flutter. I build performant, user-friendly mobile apps.

iOS Development News

Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.

We respect your privacy. You can unsubscribe at any time.

Share