npx skills add ...
npx skills add microsoft/win-dev-skills --skill winui-code-review
Code quality review for WinUI 3 apps — MVVM compliance, x:Bind correctness, accessibility, theming, security, and performance. Use before committing to catch issues that the compiler and UI tests won't find.
npx skills add microsoft/win-dev-skills --skill winui-code-review
Run a code review after the app builds and before committing. This catches quality issues that aren't build errors and aren't visible in UI tests — patterns that compile and run but are wrong, fragile, or slow.
Read through the project's XAML and C# files and check each section below. The Microsoft.WindowsAppSDK.Analyzers Roslyn analyzer ships with the winui-dev-workflow skill and is injected when BuildAndRun.ps1 calls project-mode winapp run. The wrapper supplies a temporary file through the environment-backed MSBuild CustomAfterDirectoryBuildProps hook, preserving SDK composition and each project's normal Directory.Build.props discovery (including referenced projects), then restores the environment and removes the temporary file. Plain winapp run, dotnet build, and Visual Studio do not load the analyzer automatically; to enable it outside the wrapper, add the <Analyzer Include="..." /> and <Import Project="..." /> entries to the project's own Directory.Build.props (or wait for the planned NuGet package).
The analyzer catches a curated set of WinUI 3 / Windows App SDK issues with categorized 4-digit IDs:
UwpXamlNamespace, Window.Current, CoreDispatcher, GetForCurrentView)TabView content, nested x:Bind without fallback, x:Bind without Mode, null Converter, missing AutomationId, attached-property syntax)[ObservableProperty] field syntax)WebView2 not initialized, removed ONNX Runtime GenAI APIs WUI4101-WUI4103)Every diagnostic ships at Warning severity (no rule is Error) and includes a helpLinkUri. Suppress noise with #pragma warning disable WUIxxxx or <NoWarn> as usual — the analyzer's SuppressionTests verify that pragma suppression round-trips correctly.
ObservableObject, use [ObservableProperty] partial properties (not fields)[RelayCommand] attribute, not manual ICommand implementationsSolidColorBrush, Visibility, BitmapImage) — these belong in converters or XAMLasync Task for async methods, async void only for event handlersObservableCollection<T> — use .Clear() + re-add{x:Bind}, not {Binding}Mode=OneWay or TwoWay set explicitly — OneTime default causes blank UI for dynamic datax:DataType set on every DataTemplate — required for compiled x:BindViewModel.Selected.Name) without FallbackValueMode=OneWay to Command="{x:Bind}"AutomationProperties.AutomationId on every interactive control (Button, TextBox, ComboBox, ToggleSwitch, ListView, NavigationViewItem)AutomationProperties.Name on icon-only buttons and controls without visible textButton, HyperlinkButton) — not clickable Border/TextBlock{ThemeResource} brushes — no hardcoded #FF0000 or Color="Blue"TitleTextBlockStyle, SubtitleTextBlockStyle, BodyTextBlockStyle, CaptionTextBlockStyle) — no raw FontSizeControlCornerRadius / OverlayCornerRadius — not hardcoded values{StaticResource} not {ThemeResource} (except for brush usage sites)Process.Start with unsanitized user inputFile.Delete / File.WriteAllText without validationListView/GridView (virtualized), not StackPanel with foreachx:Load for content that's not always visible (e.g., dialogs, secondary panels)Task.Run or async/await — never block UI.Result / .Wait() / .GetAwaiter().GetResult() — these deadlock the UI threadusing statements on all disposable objects (Model, Tokenizer, InferenceSession, Generator)x:Uid in XAML and ResourceLoader in C# — not hardcodedStrings/en-us/Resources.resw (not .resx)CultureInfo.CurrentCulture — not hardcoded formatsFlowDirection inherited from root, no absolute positioning that breaks in RTL)string.Format or interpolation with resource stringsAfter reviewing, summarize:
For detailed rules with code examples, see references/quality-rules.md — covers performance deep dives (x:Phase, layout optimization), security (PasswordVault, DPAPI, WebView2 hardening), accessibility (keyboard nav, screen readers), code quality (.editorconfig, naming), and globalization (x:Uid patterns, RTL, pluralization).