Skip to main content

Overview

Avalonia UI is considered by many to be the spiritual successor to WPF. While similar to WPF, it isn’t a 1:1 copy, and you’ll find plenty of improvements. This guide will help you understand the key differences and similarities to successfully migrate your WPF applications to Avalonia.
For those seeking a cross-platform WPF with minimal code changes, Avalonia XPF is a commercial product that enables WPF applications to run on macOS and Linux.

Key Similarities

Avalonia shares many core concepts with WPF:
  • XAML-based UI: Both use declarative XAML markup for defining user interfaces
  • Data binding: Full support for INotifyPropertyChanged, data binding, and MVVM patterns
  • Dependency properties: Similar property system with attached properties
  • Styling system: Resources, styles, and templates work similarly
  • Controls library: Many familiar controls with similar APIs
  • Routed events: Event bubbling and tunneling mechanisms

Major Differences

File Extensions

Avalonia uses .axaml files instead of .xaml to differentiate from WPF:
<!-- WPF: MainWindow.xaml -->
<!-- Avalonia: MainWindow.axaml -->
<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="MyApp.MainWindow">
    <!-- Content -->
</Window>

Namespace Declarations

WPF:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Avalonia:
xmlns="https://github.com/avaloniaui"

Application Entry Point

The application startup differs between WPF and Avalonia. WPF Program.cs:
public static void Main(string[] args)
{
    var app = new App();
    app.InitializeComponent();
    app.Run();
}
Avalonia Program.cs:
[STAThread]
public static void Main(string[] args)
{
    BuildAvaloniaApp()
        .StartWithClassicDesktopLifetime(args);
}

public static AppBuilder BuildAvaloniaApp()
    => AppBuilder.Configure<App>()
        .UsePlatformDetect()
        .WithInterFont()
        .LogToTrace();
The BuildAvaloniaApp() method is also used by the IDE previewer infrastructure.

Property Changes

Some properties have different names or behaviors:
WPFAvaloniaNotes
Window.AllowsTransparencyWindow.TransparencyLevelHintEnhanced transparency control
FrameworkElement.DataContextStyledElement.DataContextSame concept, different base class
Panel.ChildrenPanel.ChildrenSame API
TextBlock.InlinesTextBlock.InlinesSame API

Migration Steps

1

Set up your Avalonia project

Create a new Avalonia application using the templates:
dotnet new install Avalonia.Templates
dotnet new avalonia.app -o MyAvaloniaApp
Or use the Visual Studio Extension or JetBrains Rider which has built-in Avalonia support.
2

Update XAML files

  1. Rename .xaml files to .axaml (optional but recommended)
  2. Update the XML namespace:
    xmlns="https://github.com/avaloniaui"
    
  3. Update the schema location for IntelliSense:
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    
3

Update code-behind

Replace WPF base classes with Avalonia equivalents:
// WPF
using System.Windows;
using System.Windows.Controls;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}
// Avalonia
using Avalonia.Controls;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}
4

Update dependencies and NuGet packages

Replace WPF-specific packages:
<PackageReference Include="Avalonia" Version="11.0.0" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.0" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0" />
5

Handle platform-specific code

Avalonia uses UsePlatformDetect() to automatically configure platform backends:
AppBuilder.Configure<App>()
    .UsePlatformDetect()  // Automatically detects Windows, macOS, Linux
    .WithInterFont()       // Use Inter font family
    .LogToTrace();

Control Mapping

Most WPF controls have direct equivalents in Avalonia:
WPF ControlAvalonia ControlDifferences
ButtonButtonSame API
TextBoxTextBoxSame API
ComboBoxComboBoxSame API
DataGridDataGridRequires Avalonia.Controls.DataGrid package
TreeViewTreeViewSame API
MenuMenuSame API
ContextMenuContextMenuSame API
WindowWindowEnhanced for cross-platform

Styling Differences

WPF Styles

<Style TargetType="Button">
    <Setter Property="Background" Value="Blue"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

Avalonia Styles

<Style Selector="Button">
    <Setter Property="Background" Value="Blue"/>
    <Setter Property="Foreground" Value="White"/>
</Style>
Avalonia uses CSS-like selectors in styles, providing more powerful styling capabilities than WPF.

Data Binding

Avalonia supports the same binding syntax as WPF:
<!-- Both WPF and Avalonia -->
<TextBox Text="{Binding UserName}" />
<Button Content="Submit" Command="{Binding SubmitCommand}" />
Avalonia also supports compiled bindings for better performance:
<Window xmlns:vm="using:MyApp.ViewModels"
        x:DataType="vm:MainViewModel">
    <TextBox Text="{Binding UserName}" />
</Window>

Platform-Specific Features

Avalonia provides cross-platform abstractions while allowing platform-specific customization:
if (OperatingSystem.IsWindows())
{
    // Windows-specific code
}
else if (OperatingSystem.IsMacOS())
{
    // macOS-specific code
}
else if (OperatingSystem.IsLinux())
{
    // Linux-specific code
}

Designer Support

Avalonia provides designer support similar to WPF: Design-time properties help with previewing:
<Window xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        d:DesignWidth="800" d:DesignHeight="450">
    <!-- Content -->
</Window>

Porting Third-Party Code

When porting code from WPF or other MIT-compatible sources, include appropriate license headers:
// This source file is adapted from the Windows Presentation Foundation project. 
// (https://github.com/dotnet/wpf/) 
// 
// Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation.

Common Migration Issues

Avalonia uses StyledProperty and DirectProperty instead of DependencyProperty. Convert your properties using Avalonia’s property system.
// WPF
public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.Register(...);

// Avalonia
public static readonly StyledProperty<string> MyPropertyProperty =
    AvaloniaProperty.Register<MyControl, string>(...);
Avalonia uses avares:// URIs for resources:
<ResourceDictionary Source="avares://MyApp/Styles.axaml"/>
Some WPF controls may not have direct equivalents. Check the Avalonia.Controls namespace or community packages for alternatives.

Additional Resources

Official Documentation

Complete Avalonia documentation and tutorials

Awesome Avalonia

Community-curated list of tools and resources

Samples

Official sample applications and code examples

Community

Join the Avalonia Telegram community

Next Steps

After migrating your application:
  1. Test on multiple platforms (Windows, macOS, Linux)
  2. Review and update any platform-specific code
  3. Optimize for cross-platform performance
  4. Consider using Avalonia’s enhanced features like better styling and theming

Build docs developers (and LLMs) love