From WinUI to Cross-Platform: A Deep Dive into Uno Platform's Architecture and Design Philosophy
*Structured summary of a Chinese forum post analyzing Uno Platform's architecture.*
Key points
- In the .NET ecosystem, cross-platform UI frameworks take different approaches: Xamarin.Forms / .NET MAUI use an abstraction layer, Avalonia self-renders, and Uno Platform fully replicates the WinUI 3 API, allowing one WinUI codebase to target Windows, iOS, Android, WebAssembly, macOS, and Linux.
- Three generations of Windows UI tech: WPF (2006, managed, DirectX 9, Windows-only), UWP XAML (2015, native C++ core, XAML engine baked into the OS), and WinUI 3 (2020, decoupled from the OS release cycle via Windows App SDK, DirectX 12).
- WinUI 3's layered architecture:
- Application layer: XAML + C#/C++ business code
- Framework layer:
Microsoft.UI.Xaml.*(controls, data binding, dependency property system, Visual State Manager) - Visual layer:
Microsoft.UI.Composition(Compositor, visual tree, effects, animation) — a retained-mode API - Graphics layer: DirectX / DirectComposition with GPU acceleration
- Dependency properties are the soul of XAML, with value precedence from high to low: animated value → local value → templated value → style setter → default value, enabling styles, templates, binding, and animation to cooperate.
- API compatibility rather than abstraction: instead of designing a minimal common-denominator API like Xamarin.Forms, Uno adopts Microsoft's WinUI 3 API design directly, so developer skills and code migrate as-is.
- Dual rendering architecture:
- *Skia rendering (default)*: the C# Uno.UI framework layer draws via Google's Skia 2D engine on Metal/OpenGL/WebGL backends — pixel-identical output on every platform and full Composition API support.
- *Native rendering (legacy)*: UIElement maps to
UIViewon iOS,ViewGroupon Android, and DOM elements on WebAssembly, giving native control behavior, accessibility, and embeddability. - DependencyObject as an interface: since C# lacks multiple inheritance, a
Buttoncannot inherit bothDependencyObjectandUIView/ViewGroup. Uno turnsDependencyObjectinto anIDependencyObjectinterface, and C# source generators (e.g.,[GeneratedDependencyProperty]) emit theGetValue/SetValueimplementations at compile time. - XAML compilation via source generators: rather than WinUI's
.xbfbinary format, Uno's Roslyn-basedXamlFileGeneratorcompiles XAML into C# code (InitializeComponent,x:Namefields, compiledx:Bind), giving compile-time type checking, better runtime performance, and debuggable generated code. - Platform heads: a single shared project contains platform entry points under
Platforms/Android,Platforms/iOS,Platforms/WebAssembly, andPlatforms/Desktop. - Bait-and-switch: at compile time, code references a type-only
Uno.WinUIfacade; at publish time, the real implementation is swapped in — genuine WinUI 3 (Windows App SDK) on Windows, and Uno's reimplementations (Uno.WinUI.iOS,Uno.WinUI.Android,Uno.WinUI.WebAssembly,Uno.WinUI.Skia) elsewhere. - Platform-specific code is written via file-suffix conventions (
FilePicker.Android.cs,FilePicker.iOS.cs,FilePicker.Skia.cs) or XAML namespaces likehttp://uno.ui/androidandhttp://uno.ui/iosfor embedding native views. - MVUX (Model-View-Update-eXtended) adapts Elmish/Redux ideas to XAML: immutable
recordmodels, a single-direction data flow (View sends intents to the Model), and source-generated bindable proxies. Key abstractions: IFeed<T>— asynchronous data streams that automatically update the UIIState<T>— user-input state supporting two-way binding- FeedView elegantly handles loading / error / success states of async operations, replacing hand-managed VisualStates.
Understanding WinUI 3
Uno Platform's cross-platform strategy
Platform adaptation
Design patterns: MVUX and FeedView
Takeaway
Uno Platform shows that cross-platform UI can be achieved by faithful API reimplementation plus compile-time code generation rather than by inventing a new abstraction — preserving the WinUI ecosystem while reaching every major platform.