Skip to content
CW
Navigation

Language

Navigation

Back to Blog
10 Nov 2026 8 min read 4 Views

.NET 11 Is Here: What's New for MAUI and Blazor

.NET 11 is out. A hands-on tour of what changed for .NET MAUI and Blazor: CoreCLR by default, Hot Reload, QuickGrid, CacheView, passkeys and more.

Launch day

Today, November 10, 2026, Microsoft announced .NET 11 at .NET Conf. It is also the day .NET 8 and .NET 9 reach end of support, so if you still have apps on either one, your calendar just got a new line item.

I went through the official announcement and the release notes for MAUI and ASP.NET Core line by line. This post is the filtered version: what actually matters if you build mobile apps with .NET MAUI or web apps with Blazor, plus the code you will want to try first.

A quick note on support: .NET 11 is a Standard Term Support (STS) release with two years of support. .NET 10 remains the LTS. Also, .NET MAUI follows its own support policy, separate from the runtime lifecycle. (Sources at the end of the post, all external.)

The big picture

  • C# 15 becomes the default for net11.0, with union types, closed class hierarchies, collection expression arguments, extension indexers and labeled break/continue.
  • Runtime Async (preview) moves async suspension into the runtime, giving cleaner call stacks in profilers and debuggers.
  • The dotnet CLI is faster: a Native AOT host and an MSBuild server that stays warm between invocations.
  • Built-in Zstandard compression, a much friendlier Process API, and FullJoin in LINQ.
  • AI building blocks: Microsoft.Extensions.AI, the Microsoft Agent Framework, and an MCP server template that ships with the SDK:
dotnet new mcpserver -o MyMcpServer

Now the parts I care about most.

.NET MAUI 11: quality first

The MAUI docs describe this release as focused on product quality, and the list reads that way. Less shiny, more things that stop biting you.

CoreCLR is now the default runtime

This is the headline. Apps targeting .NET 11 run on CoreCLR instead of Mono, on Android and Apple platforms alike. On Apple platforms that disallow JIT, precompiled code and the interpreter fill the gap. NativeAOT is available as an opt-in publishing option, but on Android it is still experimental.

If you ship to production, plan a full regression pass before you flip the target framework. A runtime swap is the kind of change that shows up in the corners of your app, not in the demo.

Hot Reload and the inner loop

XAML Incremental Hot Reload is in preview, enabled by default for Debug builds. It updates live pages and controls, including supported structural edits, without navigating away. If it misbehaves in your project, you can turn it off:

<PropertyGroup>
    <EnableMauiIncrementalHotReload>false</EnableMauiIncrementalHotReload>
</PropertyGroup>

Other inner-loop upgrades:

  • dotnet run now asks for the target framework and the device, emulator or simulator.
  • dotnet watch works on Android, and on iOS with MtouchLink set to None.
  • New test templates (androidtest, iostest, maccatalysttest and friends) built on Microsoft.Testing.Platform:
dotnet new androidtest -n MyTests
cd MyTests
dotnet test

XAML gets less noisy and faster

Implicit XAML namespaces are on by default, so you no longer repeat the standard namespace declarations at the root of every file. Resource dictionaries are now lazy, with the docs citing up to about 8x faster initialization.

There is also a new x:Code directive for inline C#, but it requires EnablePreviewFeatures, so treat it as a toy for now.

Bindings got a trim-safe upgrade too. A RelativeSource with a resolvable AncestorType now compiles to an AOT-friendly binding:

<Button Command="{Binding Source={RelativeSource AncestorType={x:Type local:PeopleViewModel}},
                          Path=DeleteEmployeeCommand}" />

New controls and gestures

A built-in LongPressGestureRecognizer, finally, with no more custom behaviors:

<Image Source="dotnet_bot.png">
    <Image.GestureRecognizers>
        <LongPressGestureRecognizer Duration="500"
                                    LongPressed="OnLongPressed" />
    </Image.GestureRecognizers>
</Image>
void OnLongPressed(object sender, LongPressGestureRecognizerEventArgs e)
{
    if (e.State == GestureState.Completed)
    {
        // Handle completed long press
    }
}

BoxView now has a Fill property that accepts any brush, so gradients work without hacks. TabbedPage gets badges (BadgeText, BadgeColor, BadgeTextColor), and SwipeItem gets IconColor and TextColor with AppThemeBinding support.

The Map control got a large update: pin clustering, custom pin icons, MapLongClicked, clickable shapes, and a Windows implementation backed by Azure Maps.

Shell routes with path parameters

Routing.RegisterRoute now understands route templates. Values arrive through QueryProperty or IQueryAttributable:

Routing.RegisterRoute("trip/{tripId}", typeof(TripDetailPage));
await Shell.Current.GoToAsync("//routes/trip/SEA-204");

It currently requires absolute navigation, which is worth knowing before you refactor anything.

Platform features worth a look

  • Passkeys: a new Passkeys class in Microsoft.Maui.Authentication with IsSupported, CreateAsync (register) and AssertAsync (sign in), using standard WebAuthn JSON. Your server still owns the challenge and validation.
  • Permissions.PostNotifications is now implemented on iOS.
  • Window.StatusBarTheme for Light, Dark or Default status bar styling.
  • Themed splash screens with DarkFile, DarkColor and DarkTintColor.
  • MediaPickerOptions.SaveToGallery, which defaults to false.

Breaking changes to read before upgrading

This is the part that will cost you an afternoon if you skip it:

  • Microsoft.Maui.Controls.Compatibility no longer ships. Apps that only reference Microsoft.Maui.Controls are fine; everyone else needs to migrate.
  • Android's minimum API level goes from 21 to 24, and x86 is no longer supported.
  • On iOS and Mac Catalyst, NavigationPage and TabbedPage use new handlers. Appearing now fires before the push, so move work that assumes the page is visible to NavigatedTo.
  • Windows uses the new CollectionView2 handler by default. You can opt out temporarily with UseWindowsCollectionView2Handler set to false.
  • Color is now sealed.

Blazor in .NET 11: faster, safer, and a bit agentic

The Blazor changes live in the ASP.NET Core 11 release notes, and there are a lot of them.

Anti-forgery is on by default

Blazor Web App projects no longer need app.UseAntiforgery(). CSRF protection is automatic. That is one fewer line in Program.cs and one fewer thing to forget.

CacheView for static SSR

The new CacheView component caches the rendered output of a subtree during static SSR. On a cache hit, the markup is replayed without creating child components or running their lifecycle methods:

<CacheView VaryByQuery="category" ExpiresAfter="TimeSpan.FromMinutes(5)">
    <ProductList Category="@Category" />
</CacheView>

QuickGrid learns about URLs

QuickGrid now keeps paging and sorting state in the query string, for example ?page=2&sort=Name&direction=asc. Headers and paginator controls render as links, so it works in static SSR without any interactivity. It also has an OnRowClick parameter:

<QuickGrid Items="@people.AsQueryable()"
           OnRowClick="@((Person args) => HandleRowClick(args))">
    <PropertyColumn Property="@(p => p.Name)" />
    <PropertyColumn Property="@(p => p.Email)" />
</QuickGrid>

Heads up: if you style button.col-title, you now need to target a.col-title as well, and renaming a column title will break bookmarked URLs.

Virtualize without the fixed-height assumption

Virtualize no longer assumes every item has the same height. It relies on native CSS scroll anchoring where available. The default OverscanCount changed from 3 to 15. You can also jump to an item:

<Virtualize TItem="Product" Items="products" InitialItemIndex="500" @ref="list">
    <div class="product">@context.Name</div>
</Virtualize>

@code {
    private Virtualize<Product> list = default!;
    private List<Product> products = ProductCatalog.All;

    private async Task GoToTop() => await list.ScrollToItemAsync(0);
}

Forms: client-side and async validation

Static SSR forms with DataAnnotationsValidator now validate in the browser with no round trip. Async validation works in any render mode through AsyncValidationAttribute and IAsyncValidatableObject, so checking "is this username taken?" no longer needs a workaround.

There is also a new DisplayName component that reads labels from [Display] metadata.

TempData and session in static SSR

Flash messages are finally simple:

[SupplyParameterFromTempData]
public string? Message { get; set; }

Session values work the same way with [SupplyParameterFromSession], after you register AddSession() and call app.UseSession().

Smarter circuits for Blazor Server

  • Auto-pause on tab inactivity (opt-in, via the Microsoft.AspNetCore.Components.Server.AutoPause package) frees server memory and the SignalR connection after a configurable delay.
  • Circuit.RequestCircuitPauseAsync lets the server ask clients to pause gracefully, which is handy for deployments.
  • Circuits now receive refreshed authentication without reconnecting.

Smaller but useful

  • EnvironmentView with Include and Exclude, like the MVC environment tag helper.
  • NavigationManager.GetUriWithFragment and relative navigation options.
  • IHostedService support in Blazor WebAssembly.
  • A new Microsoft.AspNetCore.Components.Gateway dev server for standalone WebAssembly, replacing the old DevServer package.
  • Server-driven browser options through WithBrowserOptions.

Experimental: Blazor AI components

The package Microsoft.AspNetCore.Components.AI brings streaming chat, tool rendering and approval flows. It works with any IChatClient, and remote agents can connect through AG-UI. It is experimental and prerelease throughout .NET 11, so use it to learn the direction, not to build your product on it.

Beyond MAUI and Blazor

Because both frameworks sit on ASP.NET Core, a few platform features land in your lap as well:

  • C# unions work anywhere System.Text.Json is used, including Minimal APIs, SignalR and JS interop, with OpenAPI describing them as anyOf.
  • OpenAPI 3.2 is now the default for generated documents.
  • Async validation for Minimal APIs, [ShortCircuit] endpoints, and Zstandard response compression.

Should you upgrade today?

My take: install the SDK today and try your apps in a branch, but do not rush production.

  1. Update global.json if you pin the SDK, then move your target frameworks to net11.0, keeping platform suffixes.
  2. Update packages and workloads, then read the breaking changes list.
  3. For MAUI, test on real devices. CoreCLR as the default runtime is the change most likely to surprise you.
  4. For Blazor, check your CSS if you use QuickGrid, and your Virtualize layouts if you relied on the old overscan.

Installing the SDK alone does not retarget anything, so you stay in control of when each project moves.

I will follow up with a deeper post once I have migrated a real MAUI app to CoreCLR and have numbers to share.

Sources (all external)

Cezar Wagenheimer

Written by

Cezar Wagenheimer

Share this article

Comments

Have a question, or found an issue with the code? Drop a comment below — I read and reply to every one.

Loading comments…

Leave a comment

Keep exploring

Deploy // Reconectando
Reconectando ao Servidor

Uma nova versão do ecossistema está sendo aplicada. A conexão será restabelecida automaticamente em instantes.