Migrate a UWP app to WinUI 3

May 28, 2026 · View on GitHub

UWP is no longer under active development. WinUI 3 and the Windows App SDK are its successors — and AI tools can automate most of the migration. The main challenge is that AI models were trained on years of UWP samples, so without guidance they reproduce the patterns you're trying to move away from. This page gives your agent the context it needs to get it right.

Install the WinUI agent plugin

The winui-uwp-migration skill handles the common substitutions automatically:

gh copilot plugin install winui@awesome-copilot

See the WinUI agent plugin for full details.

API substitution table

The following tables summarize the most common API substitutions. For the full detailed mapping — including members, properties, and less common APIs — see Mapping UWP APIs and libraries to the Windows App SDK.

Namespaces

UWPWinUI 3
Windows.UI.Xaml.*Microsoft.UI.Xaml.*
Windows.UI.Xaml.Controls.*Microsoft.UI.Xaml.Controls.*
Windows.UI.Xaml.Media.*Microsoft.UI.Xaml.Media.*
Windows.UI.CompositionMicrosoft.UI.Composition

Threading

UWPWinUI 3
CoreDispatcherDispatcherQueue
Dispatcher.RunAsync(...)DispatcherQueue.TryEnqueue(...)
CoreApplication.MainView.CoreWindow.Dispatcherthis.DispatcherQueue (from a Window or Page)

Windowing

UWPWinUI 3
ApplicationViewAppWindow
ApplicationView.GetForCurrentView()AppWindow.GetFromWindowId(...)
ApplicationViewTitleBarAppWindowTitleBar
CoreWindowMicrosoft.UI.Xaml.Window
SystemNavigationManagerBack button via AppWindowTitleBar

Dialogs and pickers

UWPWinUI 3
MessageDialogContentDialog (set XamlRoot)
FileOpenPickerFileOpenPicker + InitializeWithWindow
FileSavePickerFileSavePicker + InitializeWithWindow
FolderPickerFolderPicker + InitializeWithWindow

Important

Pickers require InitializeWithWindow before calling PickSingleFileAsync (or similar):

var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);

ContentDialog requires XamlRoot (not InitializeWithWindow):

var dialog = new ContentDialog { XamlRoot = this.Content.XamlRoot, ... };
await dialog.ShowAsync();

Notifications

UWPWinUI 3
Windows.UI.Notifications.ToastNotificationManagerMicrosoft.Windows.AppNotifications.AppNotificationManager
Windows.UI.Notifications.BadgeUpdateManagerMicrosoft.Windows.BadgeNotifications.BadgeNotificationManager
Windows.UI.Notifications.TileUpdateManagerTiles are deprecated — use notifications or widgets
UWPWinUI 3
Frame.Navigate(typeof(MyPage))Frame.Navigate(typeof(MyPage)) — unchanged
SystemNavigationManager.BackRequestedHandle via NavigationView or AppWindow
Windows.UI.Core.Preview.SystemNavigationManagerPreviewAppWindow.Closing event

App lifecycle

UWPWinUI 3
Application.Current.SuspendingMicrosoft.Windows.AppLifecycle (requires architectural changes — see note)
Application.Current.ResumingAppInstance.GetCurrent().Activated (see note)
BackgroundTaskBuilderWindows App SDK background tasks

Note

WinUI 3 app lifecycle migration is not a simple API name swap. The Windows App SDK uses a different activation and suspension model. Treat lifecycle code as requiring a dedicated rewrite rather than automated substitution. See the Windows App SDK lifecycle documentation for the full model.

Settings and storage

UWPWinUI 3
ApplicationData.Current.LocalSettingsUnchanged
ApplicationData.Current.LocalFolderUnchanged
Windows.Storage.KnownFoldersUnchanged

APIs that don't change

Windows.Devices.*, Windows.Media.*, Windows.UI.ViewManagement.UISettings, Windows.UI.Color, and most WinRT APIs outside the XAML namespace are unchanged.

Starter prompt

I'm migrating a UWP app to WinUI 3 using the Windows App SDK.

Apply these substitutions:
- Windows.UI.Xaml.* → Microsoft.UI.Xaml.*
- CoreDispatcher / Dispatcher.RunAsync → DispatcherQueue.TryEnqueue
- ApplicationView → AppWindow + AppWindowTitleBar
- CoreWindow → Microsoft.UI.Xaml.Window
- MessageDialog → ContentDialog (set XamlRoot, not InitializeWithWindow)
- FileOpenPicker / FileSavePicker / FolderPicker → add InitializeWithWindow
- Windows.UI.Notifications → Microsoft.Windows.AppNotifications
- SystemNavigationManager.BackRequested → NavigationView back handling

Do not use any Windows.UI.Xaml.* namespaces in new code.
Do not use CoreDispatcher — use DispatcherQueue.
Flag any APIs without a direct WinUI 3 equivalent rather than guessing.

Project file changes

Replace the UWP target framework:

<!-- Before (UWP) -->
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>

<!-- After (WinUI 3) -->
<TargetFramework>net10.0-windows10.0.19041.0</TargetFramework>
<WindowsSdkPackageVersion>10.0.19041.31</WindowsSdkPackageVersion>

Add the Windows App SDK package:

dotnet add package Microsoft.WindowsAppSDK