WinUI 3 is Microsoft's native UI framework for Windows desktop apps, and the Windows App SDK is the platform that ships it, decoupled from both the .NET release train and the Windows OS release train. Together they replace UWP as the recommended way to build a modern, Fluent-styled Windows app in C# and XAML, while still letting the app call any Win32 API. This guide explains what the two pieces actually are, how packaged and unpackaged deployment differ, windowing and app lifecycle, the current state of Windows AI API integration, and how WinUI 3 compares to WPF and UWP for a new project in 2026.
What Are WinUI 3 and the Windows App SDK?#
WinUI 3 is the XAML framework: the controls, the Fluent Design styling, the compiled x:Bind binding engine and the XAML compiler. The Windows App SDK, formerly known as Project Reunion, is the broader platform WinUI 3 ships inside. It also includes app lifecycle helpers, modern resource (MRT) tooling, DWriteCore text rendering, push notifications and the Windows AI APIs, all exposed as a set of NuGet packages and a runtime that installs independently of Windows itself. That decoupling is the point: the Windows App SDK supports apps back to Windows 10, version 1809, and Microsoft ships new capabilities on its own schedule rather than waiting for the next Windows release.
A WinUI 3 app targets a Win32 desktop process, not the UWP app container, which means it can multi-window, spawn ordinary Win32 threads, P/Invoke freely and reference any .NET or native library, none of which was fully available to UWP apps. As of late 2026 the Windows App SDK is at version 2.5 on its stable release channel, shipping on a steady release cadence (roughly monthly point releases through the year) alongside preview and experimental channels for apps that want early access to new APIs.
From UWP to WinUI 3: How We Got Here#
UWP shipped its own XAML stack tied tightly to the Windows SDK: to get new XAML features, you needed a new Windows version, and your users needed to be on it. WinUI 3 pulled that same XAML stack out of the OS and into the Windows App SDK, so it now versions independently and works down-level. UWP is still present on Windows and still serviced, but Microsoft's guidance for new native Windows apps is WinUI 3, and most new investment (controls, Fluent updates, AI integration) lands there rather than in UWP's Windows.UI.Xaml namespace. If you maintain a UWP app today, the realistic paths forward are migrating its XAML to WinUI 3 in place or wrapping legacy screens with Blazor Hybrid or .NET MAUI for cross-platform reach; there is no supported route from UWP to a cross-platform target without an app-model change.
Getting Started: A Minimal WinUI 3 App#
Visual Studio's Blank App, Packaged (WinUI 3 in Desktop) template is the fastest way to start; it produces an SDK-style project targeting a Windows 10 version-specific TFM and referencing the Windows App SDK:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>ContosoDesk</RootNamespace>
<UseWinUI>true</UseWinUI>
<Nullable>enable</Nullable>
<WindowsPackageType>MSIX</WindowsPackageType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.*" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.*" />
</ItemGroup>
</Project>A window is XAML plus a code-behind partial class, and WinUI 3's headline binding feature is x:Bind: it resolves properties at compile time instead of by reflection, so a typo becomes a build error and bindings run measurably faster than WPF's {Binding}:
<Window x:Class="ContosoDesk.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Padding="16" Spacing="8">
<TextBlock Text="{x:Bind ViewModel.Title}" Style="{ThemeResource TitleTextBlockStyle}" />
<Button Content="Refresh" Click="{x:Bind ViewModel.RefreshAsync}" />
</StackPanel>
</Window>namespace ContosoDesk;
public sealed partial class MainWindow : Window
{
public MainViewModel ViewModel { get; }
public MainWindow(MainViewModel viewModel)
{
ViewModel = viewModel;
InitializeComponent();
}
}Packaged vs Unpackaged Apps#
A WinUI 3 app can deploy three ways, and the choice affects how much OS integration you get and how you ship the Windows App SDK runtime itself:
- Packaged (MSIX). The default. The app gets package identity, which unlocks features like background tasks, share targets and reliable install/uninstall/update, and the Windows App SDK runtime can be referenced as a framework-dependent package. This is the right default for Store and enterprise-managed distribution.
- Packaged with external location. MSIX-packaged for identity and servicing, but the app's files live outside the package (useful for large apps, or installers that are not MSIX-native). It still needs the Windows App SDK runtime deployed and initialized through the Bootstrapper API.
- Unpackaged. A plain EXE with no package identity, the traditional xcopy/MSI deployment model. Unpackaged apps must deploy the Windows App SDK runtime themselves (via the redistributable installer or by carrying the MSIX packages in their own setup) and call the Bootstrapper API at startup; they also need the Visual C++ Redistributable installed. The Dynamic Dependencies API lets an unpackaged app resolve other framework packages the same way a packaged app would.
For most C# projects you never call the Bootstrapper API by hand: setting <WindowsPackageType>None</WindowsPackageType> and <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained> in the project file makes the SDK generate the bootstrapping and self-contained deployment for you.
<PropertyGroup>
<WindowsPackageType>None</WindowsPackageType>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>Lacking package identity still matters for a handful of WinRT APIs that require it (some notification and share-target scenarios), so check a given API's requirements before committing to unpackaged deployment for a feature-rich app.
Windowing and the App Lifecycle#
Every WinUI 3 window wraps an AppWindow, which is what you use for anything beyond basic show/hide: resizing, positioning, a custom title bar, or presenting as compact overlay or full screen.
var appWindow = this.AppWindow;
appWindow.SetPresenter(AppWindowPresenterKind.Default);
appWindow.Resize(new Windows.Graphics.SizeInt32(1000, 700));
if (AppWindowTitleBar.IsCustomizationSupported())
{
var titleBar = appWindow.TitleBar;
titleBar.ExtendsContentIntoTitleBar = true;
titleBar.ButtonBackgroundColor = Microsoft.UI.Colors.Transparent;
}App lifecycle is handled through Microsoft.Windows.AppLifecycle, which gives WinUI 3 the single-instancing and activation redirection that used to be UWP-only. A common pattern is redirecting a second launch to the already-running instance instead of opening a duplicate window:
var activationArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
var mainInstance = Microsoft.Windows.AppLifecycle.AppInstance.FindOrRegisterForKey("main");
if (!mainInstance.IsCurrent)
{
await mainInstance.RedirectActivationToAsync(activationArgs);
Process.GetCurrentProcess().Kill();
return;
}Register for the Activated event on mainInstance to handle the redirected activation, such as bringing the existing window to the foreground and opening whatever file or URI the second launch was passed.
Controls, Fluent Design and Compiled Bindings#
WinUI 3 controls implement Fluent Design out of the box: rounded corners, acrylic and Mica backdrops, reveal-style focus visuals and light/dark themes that follow the Windows setting automatically through ElementTheme. x:Bind is the other defining feature: because it is compiled, it supports binding directly to methods (as the Click="{x:Bind ViewModel.RefreshAsync}" example above shows), function bindings for one-way conversions without a IValueConverter, and it is trim- and Native-AOT-friendly since there is no runtime reflection involved. The trade-off is that x:Bind defaults to one-time binding for performance and needs Mode=OneWay or Mode=TwoWay spelled out explicitly when a value can change, which trips up developers coming from WPF's always-live {Binding}.
Windows AI APIs#
The Windows App SDK ships a dedicated Microsoft.WindowsAppSDK.AI package bringing a set of on-device AI capabilities directly into Win32 desktop apps, alongside platform features exposed to any app such as Click to Do and Recall. The current API set includes:
- Phi Silica β a small local language model for on-device text generation and summarization, avoiding a network round trip to a cloud model.
- Text Recognition API β OCR: extracting text from images without a third-party library.
- Imaging SDK and Image generation API β on-device image processing and text-to-image generation.
- Video super resolution and App Content Search β additional on-device media and search capabilities.
Most of these APIs target Copilot+ PCs with an on-device NPU for acceptable performance, and availability depends on the Windows build and hardware the app runs on, so treat them as progressively-enhanced features rather than a hard dependency: check API availability at runtime and fall back to a cloud model through Microsoft.Extensions.AI or Azure OpenAI when a device lacks the required hardware. Because this surface is still evolving quickly, confirm exact namespaces and method signatures against the current Windows AI API documentation before you ship, rather than relying on a code sample that may already be stale.
Deployment#
Packaged apps publish as an MSIX package, either for sideloading, enterprise deployment (Intune, or an MSIX app attach), or the Microsoft Store, and get automatic updates when distributed through the Store or an App Installer file. Unpackaged and packaged-with-external-location apps publish like any other .NET desktop app:
dotnet publish src/ContosoDesk -c Release -r win-x64 `
-p:WindowsPackageType=None -p:WindowsAppSDKSelfContained=true -p:SelfContained=trueFor Store submission, build an MSIX package from Visual Studio's Create App Packages wizard or msbuild -t:Publish -p:GenerateAppxPackageOnBuild=true, sign it, and validate it with the Windows App Certification Kit before uploading. Whichever path you choose, pin the Microsoft.WindowsAppSDK package version explicitly in CI rather than floating on a version range, so a new Windows App SDK release cannot change your app's behavior without a deliberate upgrade.
WinUI 3 vs WPF vs UWP#
| WinUI 3 | WPF | UWP | |
|---|---|---|---|
| App model | Win32 desktop | Win32 desktop | UWP app container |
| Fluent Design | Default | Opt-in (.NET 9+, still expanding) | Default |
| Binding | Compiled x:Bind | Reflection-based {Binding} | Compiled x:Bind |
| Win32/P-Invoke access | Full | Full | Restricted by the app container |
| Native AOT / trimming | Supported | Not supported | Not supported |
| Release cadence | Independent, ~monthly (Windows App SDK) | Yearly, with .NET | Tied to Windows OS releases |
| Best fit today | New Windows-only apps wanting Fluent and modern APIs | Mature line-of-business apps, rich third-party control ecosystem | Legacy UWP apps under maintenance |
Best Practices#
- Pin the Windows App SDK version in your project file and upgrade deliberately; do not float on
*in a shipped product. - Default to packaged (MSIX) unless you have a specific reason not to; you get more OS integration for less code.
- Spell out
x:Bindmodes explicitly (Mode=OneWay/TwoWay) rather than relying on the one-time default and being surprised later. - Treat Windows AI APIs as optional enhancements, gated on hardware and OS version checks, not a required code path.
- Use
AppWindowfor all windowing, including multi-window apps, instead of mixing it with olderCoreWindow-era APIs that do not apply outside UWP. - Register single-instancing early in
main, before any UI is created, so a redirected activation never flashes a second window.
Common Pitfalls#
- Assuming UWP APIs port unchanged. Some
Windows.*WinRT APIs behave differently, or require package identity, outside the UWP app container. - Forgetting the Bootstrapper API for unpackaged or external-location apps. Without it (or the
WindowsAppSDKSelfContainedMSBuild property), the app fails to find the Windows App SDK runtime at startup. - Leaving
x:Bindimplicitly one-time on a value that changes, producing a UI that silently never updates. - Shipping a Windows AI API call with no fallback, which breaks the app on hardware without an NPU or on an unsupported Windows build.
- Mixing MSIX and non-MSIX assumptions, such as writing to the install directory at runtime, which works unpackaged but fails for a packaged app's read-only package folder.
Frequently Asked Questions#
Is WinUI 3 ready to replace WPF for new Windows apps?#
For a Windows-only app with no legacy investment, yes: WinUI 3 gives you Fluent Design by default, compiled bindings and Native AOT support that WPF lacks. Teams with a large existing WPF codebase, heavy use of third-party WPF control suites, or need for the more mature WPF designer often get better short-term velocity staying on WPF; see the WPF guide for that side of the comparison.
What is the difference between WinUI 3 and the Windows App SDK?#
WinUI 3 is the XAML UI framework: controls, styling and x:Bind. The Windows App SDK is the larger platform that ships WinUI 3 alongside app lifecycle APIs, resource management, notifications and the Windows AI APIs, all versioned and deployed independently of the Windows OS. You always get WinUI 3 by taking a dependency on the Windows App SDK; you cannot use one without the other.
Should a new app be packaged or unpackaged?#
Default to packaged (MSIX) for the identity, servicing and OS integration it gives you for free. Choose unpackaged only when you have a specific constraint, such as an existing non-MSIX installer, enterprise tooling that assumes traditional EXE deployment, or a need to write to arbitrary file system locations that a packaged app's sandboxing restricts.
Do Windows AI APIs require a Copilot+ PC?#
Many of them, including Phi Silica, are designed around on-device NPU acceleration and perform best, or are only available, on Copilot+ PC hardware. Always check the API's reported availability at runtime and provide a cloud-based or degraded fallback for devices without the required hardware or Windows build.
Can I mix WinUI 3 with Blazor or other web UI?#
Yes. WebView2, which ships as part of the platform story here, lets a WinUI 3 window host web content, and Blazor Hybrid can render Razor components inside that surface using the same BlazorWebView pattern available to WPF and .NET MAUI, letting you mix native WinUI 3 chrome with shared web-based screens.
Is UWP dead?#
UWP is not removed and existing UWP apps keep working and receive servicing, but it is no longer where Microsoft puts new native-app investment. New apps should start on WinUI 3 and the Windows App SDK; long-lived UWP apps should plan a migration when their roadmap allows it, rather than building new UWP-only features.
Summary#
- WinUI 3 is the XAML framework; the Windows App SDK is the platform, including app lifecycle, resources and Windows AI APIs, that ships it independent of the Windows OS release cycle.
- Choose packaged (MSIX) deployment by default; use the Bootstrapper API or the
WindowsAppSDKSelfContainedMSBuild property for unpackaged or externally-located apps. AppWindowhandles windowing and custom title bars;Microsoft.Windows.AppLifecycle.AppInstancehandles single-instancing and activation redirection.- Windows AI APIs such as Phi Silica ship in
Microsoft.WindowsAppSDK.AI, but are hardware- and OS-dependent, so gate them behind availability checks. - For a Windows-only app with no WPF legacy, WinUI 3 is the more modern choice; WPF still wins on ecosystem maturity and existing investment.