Using the Skia Desktop
Uno Platform supports running applications using a common Skia Desktop shell, which is automatically used based on the running platform, using a single build output using the net10.0-desktop target framework from the Uno.Sdk.
The currently supported targets and platforms are:
- Linux X11
- Linux Framebuffer
- Windows (Using Win32 shell)
- macOS (Using an AppKit shell)
The set of supported platforms can be defined by using the UnoPlatformHostBuilder, introduced in Uno Platform 5.2 and the Single Project support.
Get started with the Skia Desktop head
Follow the getting started guide for VS Code or Visual Studio, making sure to use the latest Uno Platform templates.
Once created, in the Platforms/Desktop/Program.cs file, you'll find the following builder:
var host = UnoPlatformHostBuilder.Create()
.App(() => new App())
.UseX11()
.UseLinuxFrameBuffer()
.UseMacOS()
.UseWin32()
.Build();
host.Run();
This builder allows us to configure the host and set up which platforms will be supported at runtime. The builder evaluates the platform's availability one by one, in the order of definition.
Additional setup
Install the required dependencies:
sudo apt update sudo apt install mesa-utils libgl1-mesa-glx ttf-mscorefonts-installer dbus libfontconfig1 libxrandr2 libxi-dev
You may also need to install the Microsoft fonts manually.
If you are using Windows Subsystem for Linux (WSL), you can find specific instructions in the following video:
Troubleshooting OpenGL integration
Enabling debug logging messages for the Skia Host can help diagnose the render surface type selection.
In your App.xaml.cs file, change the minimum log level to:
builder.SetMinimumLevel(LogLevel.Debug);
Then change the logging level of the Skia Host to Information or Debug:
builder.AddFilter("Uno.UI.Runtime.", LogLevel.Information);
You may also need to initialize the logging system earlier than what is found in Uno.UI's default templates by calling this in Main:
YourAppNamespace.App.ConfigureFilters(); // Enable tracing of the Skia host
Upgrading to a later version of SkiaSharp
By default, the Uno.Sdk brings a tested set of SkiaSharp and HarfBuzzSharp packages. To move to a different version, change the native and the managed packages together, to the same version:
- The
SkiaSharpVersionandHarfBuzzSharpVersionproperties retarget the native-asset packages the Uno.Sdk references for each platform. - The managed
SkiaSharp,SkiaSharp.SkottieandHarfBuzzSharppackages come through the Uno Platform packages, so reference them directly at the same version.
In your project file:
<PropertyGroup>
<SkiaSharpVersion>4.156.0</SkiaSharpVersion>
<HarfBuzzSharpVersion>14.4.0.100</HarfBuzzSharpVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SkiaSharp" />
<PackageReference Include="SkiaSharp.Skottie" />
<PackageReference Include="HarfBuzzSharp" />
</ItemGroup>
And in Directory.Packages.props:
<ItemGroup>
<PackageVersion Include="SkiaSharp" Version="4.156.0" />
<PackageVersion Include="SkiaSharp.Skottie" Version="4.156.0" />
<PackageVersion Include="HarfBuzzSharp" Version="14.4.0.100" />
</ItemGroup>
If your project doesn't use Central Package Management, set the Version on the PackageReference items instead.
Important
SkiaSharp checks its native library when the app starts. If the managed SkiaSharp package and the native libSkiaSharp library have different versions, the app fails at startup with "The version of the native libSkiaSharp library (…) is incompatible with this version of SkiaSharp". Setting only SkiaSharpVersion moves the native packages but not the managed one, so always reference the managed packages too. For the versions the Uno.Sdk manages, see Using the Uno.Sdk.
SkiaSharp 4
SkiaSharp 4.0 reached general availability as 4.148.0, and Uno Platform is a co-maintainer of SkiaSharp. Since Uno Platform 7.0, SkiaSharp 4 is the default — the Uno.Sdk resolves the SkiaSharp package group at a 4.x version, and the steps above move it to another version. SkiaSharp 4 turns several long-deprecated APIs into compile errors (for example, text APIs that moved from SKPaint to SKFont), so a project carrying its own SkiaSharp code from 3.x may need small changes before it builds.
Rendering Backend Selection
By default, Uno Platform tries the GPU backends in a fixed order (Vulkan, then OpenGL, then software) and uses the first available one. You can force a single backend, or disable specific ones, per platform using the host builder:
var host = UnoPlatformHostBuilder.Create()
.App(() => new App())
.UseX11(b => b.ForceRenderingBackend(X11RenderingBackend.Vulkan)) // only Vulkan
.UseWin32(b => b.DisableRenderingBackends(Win32RenderingBackend.Vulkan)) // everything except Vulkan
.UseMacOS()
.Build();
Each platform exposes its own RenderingBackend enum with only the backends it supports. ForceRenderingBackend restricts negotiation to that one backend; DisableRenderingBackends removes the listed backends and leaves the rest. For details, see Vulkan Rendering Backend.
Alternatively, you can use FeatureConfiguration.Rendering flags for backwards compatibility. The builder API takes precedence when both are used.
X11 Specifics
When running using X11 Wayland compatibility (e.g. recent Ubuntu releases), DPI scaling cannot be determined in a reliable way. In order to specify the scaling to be used by Uno Platform, set the UNO_DISPLAY_SCALE_OVERRIDE environment variable. The default value is 1.0.
The X11 support uses DBus for various interactions with the system, such as file selection. Make sure that dbus is installed.
.NET Native AOT support
Building an Uno Platform Skia Desktop app with .NET (7+) Native AOT requires Uno Platform 4.7 (or later). Uno Platform 6.6 improves support for .NET Native AOT.
To build an app with this feature enabled:
Add the following property in your
.csproj:<PropertyGroup> <PublishAot>true</PublishAot> </PropertyGroup>When using Uno Platform before Uno Platform 6.6, add the following items in your
.csproj:<ItemGroup> <TrimmerRootAssembly Include="MyApp" /> </ItemGroup>Build your app with:
dotnet publish -c Release -f net10.0-desktopNote
Cross-compilation support is not supported as of .NET 7. To build a Native AOT app for Linux or Mac, you'll need to build on the corresponding host.
Note
.NET Native AOT on Windows is not yet supported as WPF does not support it at this time.
Automatic Binding Preservation
When building an Uno Platform application head (for example, a Skia Desktop head) with Native AOT, Uno Platform automatically preserves public properties of types referenced by [Bindable] types to ensure data binding works correctly at runtime. This happens automatically when both IsUnoHead=true and PublishAot=true are set on the project (Uno head templates set IsUnoHead for you).
Note
Automatic binding preservation is only available for Uno Platform application heads. Class libraries or other projects that set PublishAot=true but are not marked with IsUnoHead=true will not get this behavior.
The build system:
- Finds all types marked with
Microsoft.UI.Xaml.Data.BindableAttributeorUno.Extensions.Reactive.Bindings.BindableAttribute - Discovers types referenced by public properties of those bindable types
- Generates an ILLink descriptor file to preserve the public properties (getters/setters) of discovered types
For example, if you have:
[Bindable]
public class MainViewModel
{
public Entity MyEntity { get; set; }
}
public record Entity(string Name);
The build system will automatically preserve the Name property of Entity, allowing {Binding MyEntity.Name} expressions to work correctly in Native AOT builds.
For more information, see the runtime documentation and the .NET Native AOT documentation.