Introduction
.NET Multi-platform App UI (.NET MAUI) is Microsoft's cross-platform UI framework for building native mobile and desktop applications using C# and .NET.
With .NET MAUI, developers can create applications that target multiple platforms from a shared codebase, including:
Android
iOS
macOS
Windows
Tizen
.NET MAUI provides a common development model while still allowing applications to use platform-specific functionality when required.
This article provides a practical introduction to .NET MAUI using the current .NET 10 platform. Instead of only discussing the framework at a high level, we will create a simple application and understand the important parts of a .NET MAUI project.
Why Use .NET MAUI?
1. Shared Codebase
.NET MAUI allows developers to share application logic, UI definitions, resources, and services across supported platforms.
For example, the same C# service can often be used by an Android, iOS, macOS, and Windows version of an application.
This can reduce duplicated development and maintenance work.
2. Native Platform Integration
.NET MAUI provides controls and APIs for building native applications while also allowing developers to access platform-specific functionality.
Applications can interact with capabilities such as:
Camera
GPS
Sensors
Device storage
Network connectivity
Notifications
Platform-specific implementations can be placed inside the Platforms folder when common code is not sufficient.
3. C# and .NET Ecosystem
.NET MAUI uses C# and the broader .NET ecosystem.
Developers can use familiar .NET technologies and patterns such as:
Dependency injection
Configuration
Async/await
MVVM
NuGet packages
HTTP clients
.NET libraries
4. XAML Support
.NET MAUI supports XAML for defining user interfaces.
This allows developers to separate UI definitions from application logic.
For example:
<VerticalStackLayout>
<Label Text="Welcome to .NET MAUI!" />
<Button Text="Click Me" />
</VerticalStackLayout>
Setting Up the .NET MAUI Development Environment
For current .NET MAUI development on Windows, Microsoft requires Visual Studio 2022 version 17.12 or later, or Visual Studio Code with the .NET MAUI extension.
Prerequisites
Install the following:
Visual Studio 2022 17.12 or later
.NET 10 SDK
.NET MAUI workload
Android emulator or physical Android device for Android development
For iOS and Mac Catalyst development, a compatible Mac with the required version of Xcode is also required.
.NET 10 is currently an LTS release and is supported until November 14, 2028.
Install the .NET MAUI Workload
If the workload was not installed through Visual Studio Installer, it can be installed using the .NET CLI:
dotnet workload install maui
You can verify the installed SDK with:
dotnet --version
To view installed workloads:
dotnet workload list
Creating a New .NET MAUI Application
After installing the required tools, create a new application.
Step 1: Open Visual Studio
Open Visual Studio and select:
Create a new project
Step 2: Select the Project Template
Search for:
.NET MAUI App
Select the template and click Next.
Step 3: Configure the Project
Enter the project name and location.
For example:
Project Name: MauiDemo
Click Create.
Visual Studio creates the project with the files and folders required for a .NET MAUI application.
Understanding the .NET MAUI Project Structure
A typical .NET MAUI project contains several important files and folders.
MauiDemo
│
├── App.xaml
├── App.xaml.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── MauiProgram.cs
│
├── Platforms
│ ├── Android
│ ├── iOS
│ ├── MacCatalyst
│ └── Windows
│
└── Resources
├── AppIcon
├── Fonts
├── Images
├── Raw
└── Splash
MainPage.xaml
MainPage.xaml defines the user interface of the main page.
For example:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiDemo.MainPage">
<VerticalStackLayout Padding="30"
Spacing="20">
<Label Text="Welcome to .NET MAUI!"
FontSize="24"
HorizontalOptions="Center" />
<Button Text="Click Me"
Clicked="OnButtonClicked" />
</VerticalStackLayout>
</ContentPage>
MainPage.xaml.cs
MainPage.xaml.cs contains the C# logic associated with the page.
For example:
private void OnButtonClicked(object sender, EventArgs e)
{
if (sender is Button button)
{
button.Text = "Clicked!";
}
}
App.xaml
App.xaml can contain application-level resources and styles.
For example, common colors, styles, and resource definitions can be shared across pages.
App.xaml.cs
App.xaml.cs contains the application's App class and is responsible for application-level initialization.
MauiProgram.cs
MauiProgram.cs is where the .NET MAUI application is configured.
It is also commonly used to register services for dependency injection.
A basic configuration looks like this:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>();
return builder.Build();
}
}
Platforms Folder
The Platforms folder contains platform-specific code.
It includes directories for platforms such as:
Platforms
├── Android
├── iOS
├── MacCatalyst
└── Windows
This allows developers to keep platform-specific implementations separate from shared application code.
Resources Folder
The Resources folder contains shared application resources such as:
Images
Fonts
Application icons
Splash screens
Raw resources
Styles
Creating a Simple .NET MAUI Application
Now let's create a simple application that displays a message and changes it when a button is clicked.
Step 1: Create the User Interface
Open MainPage.xaml and replace its contents with:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiDemo.MainPage">
<VerticalStackLayout Padding="30"
Spacing="20"
VerticalOptions="Center">
<Label x:Name="MessageLabel"
Text="Welcome to .NET MAUI!"
FontSize="24"
HorizontalOptions="Center" />
<Button Text="Click Me"
Clicked="OnButtonClicked" />
</VerticalStackLayout>
</ContentPage>
The VerticalStackLayout arranges the controls vertically.
The Label displays the initial message, while the Button provides an interaction point.
Step 2: Add the Button Logic
Open MainPage.xaml.cs:
namespace MauiDemo;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void OnButtonClicked(object sender, EventArgs e)
{
MessageLabel.Text = "Hello from .NET MAUI!";
}
}
When the user clicks the button, the text of the label changes.
Step 3: Run the Application
Select a target platform from Visual Studio.
For example:
Windows Machine
or an Android emulator.
Click Run.
The application will build and launch on the selected platform.
Adding Dependency Injection
.NET MAUI provides dependency injection support through the application's service collection.
For example, create a service:
public class GreetingService
{
public string GetGreeting()
{
return "Hello from GreetingService!";
}
}
Register it in MauiProgram.cs:
builder.Services.AddSingleton<GreetingService>();
The service can then be injected into a page:
public partial class MainPage : ContentPage
{
private readonly GreetingService _greetingService;
public MainPage(GreetingService greetingService)
{
InitializeComponent();
_greetingService = greetingService;
}
}
Dependency injection helps separate application components and makes services easier to manage and test.
Using MVVM in .NET MAUI
For larger applications, keeping UI logic inside code-behind files can make the application difficult to maintain.
The Model-View-ViewModel (MVVM) pattern separates the user interface from application logic.
A simplified structure can look like:
View
|
v
ViewModel
|
v
Service
|
v
Data Source
For example:
public class MainViewModel
{
public string Message { get; set; } = "Welcome to .NET MAUI!";
}
The XAML page can then bind to the ViewModel instead of directly modifying controls from code-behind.
This approach becomes particularly useful as an application grows.
Important .NET MAUI Features
Cross-Platform Controls
.NET MAUI provides controls such as:
Button
Label
Entry
CollectionView
Image
Picker
Switch
Slider
WebView
These controls can be used in shared application code.
Dependency Injection
.NET MAUI integrates with the .NET dependency injection system, allowing services and other dependencies to be registered and consumed throughout the application.
Blazor Hybrid
.NET MAUI can host Blazor components using Blazor Hybrid.
This allows developers to combine native .NET MAUI functionality with Razor-based UI components.
This can be useful when an organization already has reusable Blazor UI components or wants to share UI code between web and native applications.
Hot Reload
Visual Studio provides Hot Reload capabilities that can make UI development faster by allowing developers to see certain changes without manually restarting the application.
Platform-Specific Development
When common code is not enough, platform-specific implementations can be added under the appropriate Platforms directory.
.NET MAUI also provides handlers that allow developers to customize how controls map to native platform controls.
What's New in .NET MAUI with .NET 10?
.NET MAUI continues to evolve with the .NET platform.
.NET 10 focuses heavily on product quality and includes improvements across .NET MAUI, Android, iOS, Mac Catalyst, macOS, and related platform technologies.
Some notable areas include:
.NET Aspire Integration
.NET MAUI in .NET 10 includes a project template that can integrate with .NET Aspire service defaults.
This can provide capabilities such as:
OpenTelemetry metrics
OpenTelemetry tracing
Service discovery
HttpClientintegration with service discovery
For applications that communicate with multiple backend services, this can simplify service connectivity and observability.
CollectionView and CarouselView Improvements
.NET 10 includes improvements to CollectionView and CarouselView.
The improved handlers that were optional in .NET 9 are the default handlers for these controls in .NET 10.
XAML Source Generation
.NET 10 introduces a XAML source generator that generates strongly typed code for XAML at compile time.
It can be enabled with:
<PropertyGroup>
<MauiXamlInflator>SourceGen</MauiXamlInflator>
</PropertyGroup>
This can improve build performance and tooling support.
Animation API Changes
Several animation methods have been replaced with asynchronous versions.
For example:
FadeTo()
has been replaced by:
FadeToAsync()
Similar changes apply to other animation methods such as ScaleTo, RotateTo, and TranslateTo.
MessagingCenter Changes
MessagingCenter has been made internal in .NET 10.
For new applications, Microsoft recommends considering alternatives such as WeakReferenceMessenger from the CommunityToolkit.Mvvm package where an application requires a messenger pattern.
Common Use Cases
.NET MAUI can be used for many types of applications.
Business Applications
Organizations can use .NET MAUI to create applications for employees, customers, and internal business processes.
Mobile Applications
Applications can target Android and iOS while sharing common application logic.
Desktop Applications
The same development model can also target Windows and macOS.
Connected Applications
.NET MAUI applications can communicate with REST APIs and other backend services using standard .NET networking APIs.
Device-Based Applications
Applications that need access to device capabilities such as sensors, cameras, location, or local storage can use .NET MAUI and platform-specific APIs where necessary.
Best Practices
1. Use MVVM for Larger Applications
Separating the View, ViewModel, and application services helps keep larger applications maintainable.
2. Keep Shared Code Platform-Neutral
Place common business logic in shared projects or shared application code whenever possible.
Use platform-specific implementations only when the functionality cannot be handled through common APIs.
3. Avoid Excessive UI Nesting
Deeply nested layouts can make UI rendering more complicated.
Use appropriate layouts and controls for the application's requirements.
4. Test on Real Devices
Emulators are useful during development, but real devices should also be included in testing.
Different devices can have differences in:
Screen sizes
Memory
Performance
Operating system versions
Hardware capabilities
5. Keep Dependencies Updated
.NET MAUI depends on the .NET SDK, platform SDKs, workloads, and external dependencies.
Keeping these components updated within the supported version range helps avoid compatibility problems.
6. Use Platform-Specific Code Carefully
Platform-specific code should remain isolated whenever possible.
This keeps the shared application code easier to understand and maintain.
Troubleshooting Common Issues
Application Does Not Build
Check the installed .NET SDK:
dotnet --version
Then check installed workloads:
dotnet workload list
If the MAUI workload is missing, install it with:
dotnet workload install maui
Android Emulator Is Not Available
Verify that:
Android tooling is installed.
An Android emulator has been created.
The emulator is running.
Visual Studio can detect the emulator.
XAML Changes Are Not Appearing
Try rebuilding the project and verify that the correct target application is running.
Also check the XAML file for build errors and ensure the page being edited is the page currently displayed by the application.
Conclusion
.NET MAUI provides a cross-platform development model for building native applications across Android, iOS, macOS, Windows, and other supported platforms using .NET.
The framework combines shared application code with access to platform-specific functionality, allowing developers to reuse business logic while still adapting applications to individual platforms.
In this article, we created a basic .NET MAUI application, explored its project structure, created a simple interactive page, looked at dependency injection and MVVM, and reviewed several current .NET 10 MAUI capabilities.
.NET 10 is currently the active LTS release of .NET, and .NET MAUI continues to receive improvements in areas such as XAML, controls, diagnostics, platform integration, and application development workflows.

Join the conversation! Your thoughts help the community grow.