.NET MAUI (Multi-platform App UI) is Microsoft’s evolution of Xamarin.Forms, enabling developers to build native cross-platform apps for iOS, Android, macOS, and Windows from a single C# codebase. This guide covers the architecture, the single-project model, XAML vs C# markup, MVVM data binding, the control and layout catalog, and deployment pipelines, everything you need to ship production-ready .NET MAUI apps.
What Is .NET MAUI?
.NET MAUI (Multi-platform App UI) is Microsoft’s evolution of Xamarin.Forms, shipping with .NET 8 and later. It provides a unified SDK and a single-project model compiling to native platform binaries. Unlike hybrid frameworks that render inside a WebView, MAUI maps its controls to native platform widgets, your app looks, feels, and performs like a first-class citizen on every OS.
Key improvements over Xamarin.Forms include:
- Single project model. One .csproj, one solution, platform-specific folders instead of separate head projects.
- Handler architecture. Replaces custom renderers with a lighter, more testable mapping layer.
- Hot Reload. Modify XAML and C# at runtime without restarting the app.
- Built-in services. Essential APIs for file picking, share, network, sensors via
Microsoft.Maui.Essentials.
Opt for .NET MAUI when your team already has C# / .NET expertise, you need native UI fidelity on mobile and desktop, and you want to share business logic across platforms without maintaining four separate codebases.
.NET MAUI Architecture
.NET MAUI sits on top of the .NET runtime and uses platform-specific handlers to bridge abstract controls to native widgets. Understanding this layering is critical for debugging, performance tuning, and extending the framework.
IButton, IEntry) and the base View / Layout types you program against.PropertyMapper dictionary.ButtonHandler creates UIButton on iOS, AppCompatButton on Android, Button on WinUI 3.Handler vs Renderer Comparison
| Aspect | Xamarin Renderer | MAUI Handler |
|---|---|---|
| Mapping | One class per control | Property-level mapper |
| Testability | Requires platform host | Unit-testable |
| Composition | Inheritance-based | Composition-based |
| Registration | Assembly attribute | AddHandler in MauiProgram |
The Single Project Model
In Xamarin.Forms you needed up to five separate projects: a shared library plus four platform heads. .NET MAUI consolidates everything into a single project. Platform-specific code lives in Platforms/ folders, and the build system compiles the right assets for each target.
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst;net8.0-windows</TargetFrameworks>. No more head projects.
Platforms/Android/, Platforms/iOS/, Platforms/MacCatalyst/, and Platforms/Windows/. The compiler includes only the relevant folder per target.
Resources/AppIcon/, Resources/Images/, Resources/Fonts/, and Resources/Raw/. MAUI generates platform-specific asset catalogs at build time.
App class here using the MauiAppBuilder fluent API.
Use #if ANDROID, #if IOS, #if WINDOWS compiler directives inside the Platforms/ folders. For shared code, use partial classes, define the shared part in the root and the platform part in the platform folder.
Project Structure at a Glance
| Path | Purpose |
|---|---|
MauiProgram.cs |
DI container, handler registration, font/image config |
App.xaml / AppShell.xaml |
App resources and Shell navigation |
Pages/ / ViewModels/ |
XAML pages and MVVM view models |
Platforms/{Android,iOS,MacCatalyst,Windows}/ |
Platform-specific code and entry points |
Resources/ |
Images, fonts, icons, raw assets |
XAML vs C# Markup
.NET MAUI supports two ways to define UI: XAML (declarative XML) and C# Markup (fluent C# code). Both compile to the same native controls; the choice is about developer ergonomics and team workflow.
Microsoft.Maui.Controls.Markup. Type-safe, refactor-friendly, no XAML parsing overhead. Best for developers who want everything in one language and IDE navigation.Side-by-Side Comparison
| Feature | XAML | C# Markup |
|---|---|---|
| Hot Reload | Full support | Limited |
| Type safety | Compile-time with x:Name | Full compile-time |
| Refactoring | Rename with caution | Standard IDE refactoring |
| Data binding | String-based | Typed Bind() extension |
| Learning curve | XML familiarity | C# LINQ-style fluency |
Use XAML when your team includes designers, you need Hot Reload for rapid iteration, or you want to use visual state managers and triggers. Use C# Markup when your team is C#-only, you value compile-time guarantees, or you want to avoid XAML parsing overhead in hot paths.
MVVM Pattern in .NET MAUI
Model-View-ViewModel is the recommended architectural pattern for .NET MAUI. The framework provides built-in support for data binding, command binding, and change notification, the three pillars of MVVM.
BindingContext. Zero business logic, only layout and display.INotifyPropertyChanged properties and ICommand objects. Contains presentation logic, validation, and navigation triggers. Registered in DI as a scoped or transient service.Implementing INotifyPropertyChanged
ObservableObject base class or [ObservableProperty] source generator eliminates boilerplate. Install CommunityToolkit.Mvvm from NuGet.
[RelayCommand] and the source generator produces the ICommand implementation, including CanExecute support.
Wire up BindingContext. Set BindingContext in the page’s constructor or use xmlns:viewmodels with x:DataType for compiled bindings. Compiled bindings catch binding errors at build time.
AppShell via Routing.RegisterRoute. Navigate with Shell.Current.GoToAsync() and pass parameters with Dictionary<string, object>.
MVVM Binding Modes
| Mode | Direction | Use Case |
|---|---|---|
TwoWay |
View ↔ ViewModel | Form inputs, toggles |
OneWay |
ViewModel → View | Display labels, status |
OneTime |
ViewModel → View (once) | Static labels |
Always enable compiled bindings with x:DataType at the page level. They validate binding expressions at compile time, eliminating the most common runtime error in MVVM apps, misspelled property names, and they improve performance by skipping reflection.
Controls and Layouts Catalog
.NET MAUI ships with a rich set of cross-platform controls and layout containers. Each control maps to a native platform widget, ensuring consistent behavior and accessibility.
Core Controls
| Control | Purpose | Native iOS | Native Android | Native Windows |
|---|---|---|---|---|
Button |
Tap action | UIButton | AppCompatButton | Button |
Entry |
Text input | UITextField | AppCompatEditText | TextBox |
Label |
Display text | UILabel | TextView | TextBlock |
Image |
Display images | UIImageView | AppCompatImageView | Image |
Switch |
Toggle on/off | UISwitch | SwitchCompat | ToggleSwitch |
CollectionView |
Scrollable list | UICollectionView | RecyclerView | ListView |
Shell |
Navigation host | UISplitViewController | DrawerLayout | NavigationView |
Layout Containers
Prefer VerticalStackLayout / HorizontalStackLayout over StackLayout when you know the orientation at compile time. The typed variants are measurably faster because they skip the orientation-measurement pass. Similarly, prefer Grid with explicit rows/columns over nested StackLayout for complex layouts.
Building and Deploying .NET MAUI Apps
Deployment involves compiling platform-specific binaries, signing them with appropriate certificates, and publishing to app stores or distributing directly. MAUI’s single-project model simplifies the process but platform-specific requirements still apply.
ApplicationId, version, display name, and icons in .csproj and MauiProgram.cs. Each platform has its own manifest file (AndroidManifest.xml, Info.plist, Package.appxmanifest).
dotnet publish -c Release -f net8.0-android (or the appropriate target framework). Enable AOT compilation and trimming for smaller binaries: <PublishTrimmed>true</PublishTrimmed>.
bundletool or Play Console, and Microsoft Store via Partner Center. CI/CD pipelines (Azure DevOps, GitHub Actions) automate this step.
Deployment Targets and Requirements
| Platform | Output | Min OS |
|---|---|---|
| Android | AAB / APK | Android 5.0 (API 21) |
| iOS | IPA | iOS 11.0 |
| macOS | APP / PKG | macOS 10.15 |
| Windows | MSIX | Windows 10 1809 |
When PublishTrimmed is enabled, the IL linker removes unused code. Reflection-heavy libraries (JSON serializers, ORM frameworks) may break. Use [DynamicDependency] attributes or TrimmerRootAssembly to preserve required types. Test trimmed builds thoroughly before release.
Getting Started, Your First .NET MAUI App
Ready to build? Follow these steps to scaffold, run, and extend a .NET MAUI application from scratch.
dotnet workload install maui to add the MAUI SDK.
dotnet new maui -n MyFirstMauiApp. This generates the single-project structure with all platform folders, MauiProgram.cs, and a default MainPage.
dotnet add package CommunityToolkit.Mvvm. This gives you [ObservableProperty], [RelayCommand], and source-generated MVVM boilerplate.
MainViewModel with observable properties and relay commands. Set it as the BindingContext of MainPage. Enable compiled bindings with x:DataType.
dotnet run -f net8.0-android (or your target). Use Hot Reload to modify XAML and C# without restarting. Test on emulators and physical devices.
Once you have a running app, explore: Shell navigation for complex routing, MauiGraphics for custom drawing, Blazor Hybrid to embed web UI, and platform-specific APIs via Microsoft.Maui.Essentials. The official docs at learn.microsoft.com/dotnet/maui are the authoritative reference.
Dev Station works with teams across the United States and the United Kingdom. Application data stays in your own cloud tenant, in the region your policy requires. Where a client needs SOC 2, HIPAA or UK GDPR evidence, we build the technical controls those frameworks ask for and work alongside the assessor who issues the certificate. Our engineers work from Vietnam with overlap into US Eastern, US Pacific and UK GMT hours, and we invoice in USD or GBP.
Want an AI assistant to summarize or cite this guide?
Click any link below to open the AI with a pre-filled prompt referencing this article:
Talk To Us
Tell us what you are building and what it has to connect to. An engineer answers, and you get a straight view of what the work would take.
Get In Touch →


