Revision history (1 updates, last updated Sep 1, 2026)
A log of the changes made to this article. Where a pre-update version was archived, it stays readable at a permanent DOI link.
- Retranslated as a full translation of the Japanese original. The previous English version was an abridgement that carried only part of the source, so sections, tables, Mermaid diagrams, figure captions and FAQ entries were missing. All of them have been restored to match the Japanese original, and the technical claims are the same as in the Japanese version. Read the version before this update (DOI: 10.5281/zenodo.21614539)
- First published
Cite this article(DOI: 10.5281/zenodo.21614538)
This article is archived on Zenodo. Below are both the DOI that always resolves to the latest version and the DOI pinned to the version you are reading.
Go Komura (2026). Choosing Between WinForms, WPF, and WinUI - A Practical Decision Table. KomuraSoft LLC. https://doi.org/10.5281/zenodo.21614538 https://comcomponent.com/en/blog/2026/03/18/001-winforms-wpf-winui-decision-table/
- DOI (latest version)
- 10.5281/zenodo.21614538
- DOI (this version)
- 10.5281/zenodo.22217173
Who this is for: Developers who build Windows desktop applications in C# / .NET, and the people who decide their technology stack. Assumptions: Current .NET (not .NET Framework), with Windows as the only target platform. How to read this: For the conclusion alone, read sections 1 and 3. To decide how to extend the life of an existing app, start at section 7. If you want the final tie-breakers, start at section 8.
When building a Windows desktop application in C# / .NET, the quietly recurring headache is which of WinForms, WPF, and WinUI to choose.
The dangerous part is fuzzy reasoning like:
- WinUI, because it is the newest
- WinForms, because it is the most familiar
- WPF, because it feels vaguely in-between
flowchart TB
accTitle: The risk of a vague choice
accDescr: Diagram showing that vague reasons such as WinUI because it is newest, WinForms because it is most familiar, and WPF because it feels in-between are risky, and that practice calls for clearer axes.
w1["WinUI because it is newest"] --> w4["A vague way of choosing"]
w2["WinForms because it is familiar"] --> w4
w3["WPF because it feels in-between"] --> w4
w4 --> w5["In practice, use clear axes"]
Figure 1: Choose on clear axes, not on new, familiar, or vaguely in-between.
In practice, the axes to look at are a bit more concrete.
- New development, or an extension of existing assets?
- Are the screens input-form-centric, or do they need expressiveness?
- Is a modern, Windows-native UI itself the product value?
- How will you handle deployment, updates, and enterprise operations?
- Is the development style centered on the Windows Forms Designer, or on XAML / MVVM?
In this article, we organize all of this into a single decision table. Note that in this article, WinUI primarily means WinUI 3 + the Windows App SDK. 12
Also, all three of these are Windows-only. If macOS / Linux is also in scope, the problem statement is fundamentally different. 341
flowchart TB
accTitle: All three are Windows-only
accDescr: Diagram showing that WinForms, WPF, and WinUI are all Windows-only, so if macOS or Linux is in scope the problem statement itself is different.
t1["WinForms"] --> t4["All three are Windows-only"]
t2["WPF"] --> t4
t3["WinUI"] --> t4
t4 -.-> t5["If macOS / Linux is in scope, the problem differs"]
Figure 2: All three are Windows-only, and going cross-platform is a different problem statement.
1. The Conclusion First (In One Breath)
Stated rather bluntly, but in a way that is useful in practice:
- If you have a large existing WinForms application, look first at staying on WinForms
- If you have a large existing WPF application, look first at staying on WPF
- For a new small-to-medium internal tool, centered on standard controls and input screens, built quickly, WinForms is still remarkably strong 35
- For a new medium-to-large business application with many screens where you want to make proper use of data binding, styles, templates, commands, and MVVM, WPF is most often the safest choice 467
- For a new Windows-only product where a modern Windows UI, Fluent, and the latest Windows experience are directly tied to product value, WinUI is a strong candidate 12
- If you merely want to use the latest Windows APIs, WinUI is not required. WPF / WinForms can also adopt Windows App SDK features 28910
- Choosing on the premise that “we can slot in WinUI bit by bit later” is a bit risky. Incremental migration is more of a slog than it sounds 1011
In short, it comes down to roughly this:
- If your existing assets are large, preserve that lineage first
- For new development of standard forms built fast: WinForms
- For a new, long-lived Windows business application: WPF
- For new development where a modern Windows UI is itself a requirement: WinUI
- If you only want the Windows App SDK, do not jump everything to WinUI at once
Framework selection is a choice of UI technology, but it is simultaneously a choice of deployment, operations, learning cost, and migration cost. Decide it on “new versus old” alone, and the bill arrives later as deployment design work and maintenance cost.
flowchart TB
accTitle: How to reach the first conclusion
accDescr: Diagram showing the decision path where large existing assets mean keeping that lineage, new development centered on standard forms means WinForms, a long-lived Windows business application means WPF, and a modern Windows UI as the requirement itself means WinUI.
r1{"Are the existing assets large"} -->|"Yes"| r2["Keep that lineage first"]
r1 -->|"No, new development"| r3{"Standard-form-centric"}
r3 -->|"Yes"| r4["WinForms"]
r3 -->|"No"| r5{"Is a modern UI itself the requirement"}
r5 -->|"No"| r6["WPF, a long-lived business app"]
r5 -->|"Yes"| r7["WinUI"]
r7 -.-> r8["If only the SDK is wanted, do not move all of it to WinUI"]
Figure 3: Look at existing assets, the nature of the screens, and the modern-UI requirement in that order, and the conclusion mostly falls out.
Knowledge map for this article
This article organizes the choice among WinForms, WPF, and WinUI along the axes of whether the work is new development or an extension of an existing codebase and whether the UI is centered on standard forms or on expressive presentation, and it recommends WinForms for line-of-business applications built mainly from standard controls, WPF for medium to large line-of-business applications that make the most of data binding and MVVM, and WinUI for new Windows-only products where Fluent and the latest Windows experience translate directly into product value. WinUI is the UI framework part of the Windows App SDK and by default assumes an MSIX package and package identity, while the Windows App SDK itself can also add features to existing WPF and WinForms code, so a full UI migration is not mandatory, and the article warns that a staged migration through XAML Islands should be validated on a small scale before it is adopted as the main strategy.
flowchart LR
accTitle: Choosing between WinForms, WPF, and WinUI
accDescr: Diagram showing the criteria for judging whether WinForms, WPF, or WinUI fits new development or an existing codebase, that WinUI assumes Windows App SDK, MSIX, and package identity, the relationship between MVVM and data binding, and the cautions around a staged migration through XAML Islands
windows_forms["Windows Forms"]
wpf["WPF"]
winui["WinUI (Windows App SDK)"]
xaml["XAML"]
data_binding["Data binding"]
mvvm_pattern["MVVM (Model-View-ViewModel)"]
windows_app_sdk["Windows App SDK"]
msix["MSIX"]
package_identity["Package Identity"]
sparse_package["Sparse Package (External Location)"]
unpackaged_app["Unpackaged App"]
xaml_islands["XAML Islands"]
gradual_winui_migration["Incremental WinUI Migration for WPF/WinForms"]
standard_control_centric_app["Standard-Control Line-of-Business App"]
multi_screen_business_app["Multi-Screen Line-of-Business App"]
windows_native_modern_product["Windows-Only Modern Product UI"]
fluent_design["Fluent Design System"]
wpf -->|"uses"| xaml
winui -->|"uses"| xaml
wpf -->|"uses"| data_binding
mvvm_pattern -->|"requires"| data_binding
wpf -.->|"uses"| mvvm_pattern
winui -.->|"uses"| mvvm_pattern
winui -->|"implements"| windows_app_sdk
wpf -.->|"uses"| windows_app_sdk
windows_forms -.->|"uses"| windows_app_sdk
winui -.->|"requires"| msix
msix -->|"requires"| package_identity
sparse_package -->|"requires"| package_identity
unpackaged_app -->|"incompatible with"| package_identity
wpf -.->|"uses"| xaml_islands
windows_forms -.->|"uses"| xaml_islands
gradual_winui_migration -->|"requires"| xaml_islands
gradual_winui_migration -->|"not recommended for"| winui
windows_forms -->|"recommended for"| standard_control_centric_app
wpf -->|"recommended for"| multi_screen_business_app
winui -->|"recommended for"| windows_native_modern_product
windows_forms -->|"should come before"| winui
wpf -->|"should come before"| winui
windows_app_sdk -->|"should come before"| winui
winui -->|"uses"| fluent_design
In the diagram a solid line marks a relation that always holds and a dashed line marks a conditional one (the conditions are given per relation on the detail page). The full list of relations (24 in total, with evidence and certainty) and the definitions of the main concepts are collected on the knowledge map detail page (in Japanese). Data: JSON-LD / Turtle
2. The Three Technologies in This Article
First, let us align the vocabulary a little. The abbreviations that keep coming up below are spelled out here.
| Term | Expansion | Roughly speaking |
|---|---|---|
| XAML | eXtensible Application Markup Language | An XML-based markup language for writing screen structure declaratively. WPF and WinUI both use it |
| Designer | Windows Forms Designer | The Visual Studio feature for assembling screens by dragging controls. What it produces is left behind as code in *.Designer.cs |
| Data Binding | Data binding | A mechanism that ties a screen property to a data-side property so that a change on one side follows through to the other |
| MVVM | Model-View-ViewModel | A design pattern that separates the screen (View), the screen-facing state and commands (ViewModel), and the business logic and data (Model). View and ViewModel are connected by Data Binding |
| Fluent | Fluent Design System | Microsoft’s design system defining the look and feel of Windows 11. WinUI assumes it |
| Windows App SDK | - | The current set of development libraries for Windows, including WinUI. It also contains non-UI features, and it can be added to existing WPF / WinForms / Win32 apps |
| XAML Islands | - | A mechanism for embedding new XAML controls into just part of an existing WPF / WinForms / Win32 app. Covered in 5.3.3 |
| MSIX | - | The Windows app package format. Installation, updates, and uninstallation are handled by OS-level mechanisms |
| package identity | Package ID | The state in which Windows can identify which app package a process belongs to. Some Windows features, such as notifications and file associations, do not work without it |
| Technology | Roughly speaking | Strong axes |
|---|---|---|
| WinForms | The traditional .NET desktop UI for Windows, where forms are quickly assembled in the Visual Studio Designer | Fast screen building, standard controls, leveraging existing assets |
| WPF | A Windows-only UI that makes it easy to build expressive UIs using XAML, data binding, styles, templates, and commands | Medium-to-large business apps, MVVM, easy screen organization |
| WinUI | The modern Windows-native UI on top of the Windows App SDK | Fluent, the latest Windows experience, high DPI, modern product UI |
WinForms is described on Microsoft Learn as a framework with controls, graphics, data binding, and user input, making it easy to build apps with Visual Studio’s drag-and-drop Designer. 3
WPF is a highly expressive UI framework that includes resolution-independent vector-based rendering, XAML, data binding, styles / templates, 2D / 3D, and animation. 4
WinUI is part of the Windows App SDK: today’s UI framework for Windows, built around high DPI, modern input, smooth animation, and Fluent-style experiences. 12 It also has perfectly ordinary paths for data binding / MVVM. 12
What matters here is that the Windows App SDK and WinUI are not the same thing. WinUI is the UI-framework part of the Windows App SDK, but the Windows App SDK itself can also be added to existing WPF / WinForms / Win32 apps. 210
So:
- Using WinUI
- Using Windows App SDK features
look similar but are separate decisions. If the discussion runs with these two conflated, “should we migrate the UI” and “should we add a feature” get treated as the same question, and no conclusion emerges.
flowchart TB
accTitle: The Windows App SDK and WinUI are not the same
accDescr: Diagram showing that WinUI is the UI-framework part of the Windows App SDK while the SDK itself can be added to existing WPF, WinForms, and Win32 apps, so deciding to use WinUI and deciding to use SDK features are separate decisions.
sdk["Windows App SDK"] --> ui["WinUI, its UI framework part"]
sdk -.-> ex["Can also be added to WPF / WinForms / Win32"]
ui --> d1["The decision to use WinUI"]
ex --> d2["The decision to use SDK features"]
d1 --> d3["Similar-looking, but separate decisions"]
d2 --> d3
Figure 4: Using WinUI and using Windows App SDK features are two different decisions.
3. The One-Page Decision Table
First, the table that is most useful in practice.
| Situation | First choice | Reason |
|---|---|---|
| Maintaining / extending an existing WinForms app, or updating it to current .NET | Stay on WinForms | Easy to leverage existing screens, Designer assets, and control assets |
| Maintaining / extending an existing WPF app, or updating it to current .NET | Stay on WPF | Easy to keep XAML, Binding, MVVM, and screen structure intact |
| New, internal tool, settings screens, admin screens, input-form-centric | WinForms | Fast ramp-up when standard controls dominate |
| New, many screens, complex state, want styles / templates / MVVM | WPF | Easier to separate screen responsibilities and organize the UI |
| New, where a modern Windows-native UI is itself a requirement | WinUI | Easy to lean into Fluent and the latest Windows experience |
| Keep existing WPF / WinForms but want Toast / Windowing / App Lifecycle, etc. | Current framework + Windows App SDK | A full UI migration is often unnecessary just to get modern Windows features |
| Heavy dependence on COM / ActiveX / old third-party controls | Lean toward the existing framework | The dependency migration cost outweighs the UI before you even start |
| Strongly constrained by deployment / update / enterprise operations | Consider WPF / WinForms first; for WinUI, verify deployment design early | WinUI requires looking early at Windows App SDK / packaging concerns |
| Want cross-platform in the future | Reconsider, including options beyond these three | All three are Windows-only |
This table mostly suffices, but two points of frequent agonizing remain.
- For a new Windows business application, should you lean WinForms or WPF?
- You already have WPF / WinForms - should you go to WinUI?
These two become easier to judge while looking at the comparison table that follows.
flowchart TB
accTitle: The two questions left after the decision table
accDescr: Diagram showing that the one-page decision table leaves two questions, whether a new Windows business application should lean WinForms or WPF and whether to move to WinUI when WPF or WinForms already exists, and that the perspective-by-perspective comparison table helps answer them.
hyo["The one-page decision table"] --> n1["New business app: WinForms or WPF"]
hyo --> n2["Move to WinUI despite existing assets"]
n1 --> hik["Think it through with the comparison table"]
n2 --> hik
Figure 5: The two questions the decision table leaves open are worked out with the perspective-by-perspective comparison table.
4. Comparison Table by Perspective
This is not an official superiority chart - it is a heavily practice-oriented comparison.
| Perspective | WinForms | WPF | WinUI |
|---|---|---|---|
| Building small input forms quickly | Excellent | Good | Good |
| Internal tools centered on standard controls | Excellent | Good | Fair to Good |
| Affinity with data binding / MVVM | Fair | Excellent | Good to Excellent |
| Styles / templates / screen expressiveness | Fair | Excellent | Excellent |
| Affinity with existing Windows desktop assets | Excellent | Good | Fair |
| Modern Windows look and feel | Fair | Good | Excellent |
| Extending and incrementally reworking existing screens | Excellent | Excellent | Fair |
| Only want to add Windows App SDK features | Good | Good | Excellent |
| Lightness of deployment / update / operations design | Good | Good | Fair to Good |
| Building a “new, long-lived, Windows-only product UI” | Fair | Good | Excellent |
The trick to reading this is not which one is strongest but which one causes the least friction.
For example, if you have:
- An internal configuration tool
- A device settings screen
- Lists, details, search, settings, buttons
- Operational stability and rework speed mattering more than looks
then WinForms is still entirely rational.
Conversely, if you have:
- Many screens
- Lots of display-state switching
- A desire to separate views from logic
- Data changes that should flow naturally into the UI
- A desire to govern the UI through styles / templates
then WPF is highly effective. 67
And if you have:
- A Windows 11-native look as a baseline
- A desire to genuinely leverage Fluent
- High DPI, touch, and modern windowing APIs as prerequisites
- A new, Windows-only product where the UI’s impression also matters
then WinUI is the natural fit. 12
flowchart TB
accTitle: Choose by least friction
accDescr: Diagram showing that the trick is not which framework is strongest but which causes the least friction, with WinForms natural for standard-control-centric internal tools, WPF for projects with many screens that want MVVM, and WinUI where Fluent and the latest Windows experience are prerequisites.
k0["Which causes the least friction"] --> k1["Internal tools, standard controls"]
k0 --> k2["Many screens, want MVVM"]
k0 --> k3["Fluent and the latest Windows experience assumed"]
k1 --> k4["WinForms"]
k2 --> k5["WPF"]
k3 --> k6["WinUI"]
Figure 6: Pick among the three by which causes the least friction, not by which is strongest.
4.1 Seeing the Difference in Expressiveness in Minimal Code
The “affinity with data binding / MVVM” row above is hard to grasp from words alone. Here is what changes when the same screen is written in WinForms and in WPF, in the smallest code that shows it.
The screen has exactly one text box and one save button.
WinForms: the Designer generates *.Designer.cs, and the event handler pulls the value out of the screen.
// MainForm.Designer.cs - the Designer-generated side. Not a place you hand-edit
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Button saveButton;
private void InitializeComponent()
{
this.nameTextBox = new System.Windows.Forms.TextBox();
this.saveButton = new System.Windows.Forms.Button();
this.SuspendLayout();
this.nameTextBox.Location = new System.Drawing.Point(12, 12);
this.nameTextBox.Size = new System.Drawing.Size(200, 23);
this.saveButton.Location = new System.Drawing.Point(218, 12);
this.saveButton.Size = new System.Drawing.Size(75, 23);
this.saveButton.Text = "Save";
this.saveButton.Click += new System.EventHandler(this.SaveButton_Click);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.saveButton);
this.ResumeLayout(false);
}
// MainForm.cs - this is the side you write by hand
public partial class MainForm : Form
{
private readonly EditorService _service;
public MainForm(EditorService service)
{
_service = service;
InitializeComponent();
}
private void SaveButton_Click(object sender, EventArgs e)
{
// Read the value straight out of the screen control and pass it on
_service.Save(this.nameTextBox.Text);
}
}
WPF: the XAML says only what each element connects to, and the Binding moves values in and out.
<!-- MainWindow.xaml -->
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Edit" Width="360" Height="120">
<StackPanel Orientation="Horizontal" Margin="12">
<TextBox Width="200"
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<Button Width="75" Margin="6,0,0,0" Content="Save"
Command="{Binding SaveCommand}" />
</StackPanel>
</Window>
// MainWindow.xaml.cs - forget to set DataContext and the Binding does nothing at all
public partial class MainWindow : Window
{
public MainWindow(EditorService service)
{
InitializeComponent();
this.DataContext = new MainViewModel(service);
}
}
// MainViewModel.cs - the side that knows nothing about the screen. Unit tests live here too
public sealed class MainViewModel : INotifyPropertyChanged
{
private readonly EditorService _service;
private string _name = string.Empty;
public MainViewModel(EditorService service)
{
_service = service;
SaveCommand = new RelayCommand(() => _service.Save(Name));
}
public string Name
{
get => _name;
set
{
if (_name == value) return;
_name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
public ICommand SaveCommand { get; }
public event PropertyChangedEventHandler PropertyChanged;
}
RelayCommand is a small class implementing ICommand. Libraries such as CommunityToolkit.Mvvm ship one, and you can also write your own in about 20 lines.
Counting lines alone, WPF is the longer one. The difference starts to show from here.
| WinForms | WPF | |
|---|---|---|
| Where the value is read from the screen | Read nameTextBox.Text directly inside the event handler |
The Name property. The View is never touched |
| Unit-testing the save logic | You have to stand up the Form | You can new up MainViewModel directly and call it |
| Putting the same input field on a second screen | Place the control again and rewrite the handler | Point a different View at the same ViewModel |
| Unifying the look across all screens | Line up the properties of each control individually | Put the Style / Template in one place |
The practical meaning of that difference is this: at three screens WinForms is faster, and at thirty screens WPF is lighter.
flowchart TB
accTitle: The difference in how values flow
accDescr: Diagram showing that in WinForms an event handler reads values straight out of the screen controls and calls the service, while in WPF a Binding connects the View and the ViewModel and the ViewModel, which knows nothing about the screen, calls the service.
subgraph wf["WinForms"]
a1["Controls in the View"] --> a2["Event handler"]
a2 --> a3["Calls the service directly"]
end
subgraph wp["WPF"]
b1["XAML of the View"] --> b2["Binding"]
b2 --> b3["ViewModel"]
b3 --> b4["Calls the service"]
end
a3 -.-> c1["Fast at three screens"]
b4 -.-> c2["Still light at thirty screens"]
Figure 7: WinForms reads values straight from the screen, while in WPF the ViewModel takes them over through a Binding.
5. What Kinds of Projects Suit Each
5.1 WinForms
WinForms tends to be unfairly looked down on, but on the single axis of building standard-control-centric business screens fast, it remains formidable. 35
It is especially suited to projects such as:
- Internal configuration tools
- Settings screens for devices, instruments, and monitoring tools
- Admin screens, search screens, list + detail
- Projects with large existing WinForms assets
- Teams whose development style is strongly centered on the Windows Forms Designer
WinForms’s strength is that, without importing any difficult philosophy, you get screens close to a finished product reasonably fast. Forms, buttons, labels, text boxes, data grids. If that is the world you work in, WinForms holds up very well.
But its weaknesses are equally clear.
- Wanting to broadly unify the look of the entire application
- Wanting to control the UI through styles and templates
- Wanting to handle complex state changes primarily through data binding
- Wanting clean separation of screen logic
For these, WPF and WinUI are more straightforward.
Build a large app in WinForms and, the moment you relax, it tends to become a jungle of event handlers. So if you choose WinForms, it is more peaceful to decide at least the following from the start:
- Keep per-screen responsibilities small
- Split things into UserControls
- Maintain a Presenter / ViewModel-like boundary
- Do not smear business logic across screen event handlers
flowchart TB
accTitle: Avoiding a jungle of event handlers
accDescr: Diagram showing that a large WinForms app easily turns into a jungle of event handlers, so keeping per-screen responsibilities small, splitting into UserControls, and being deliberate about boundaries should be decided from the start.
mo["A large WinForms app"] --> ha["Easily becomes a jungle of event handlers"]
ha --> p1["Keep screen responsibilities small"]
ha --> p2["Split into UserControls"]
ha --> p3["Be deliberate about boundaries"]
p3 -.-> p4["No business logic in screen events"]
Figure 8: A large WinForms app stays peaceful if the rules for splitting responsibilities are set from the start.
Also, something that matters a great deal in practice: wanting the Windows App SDK is not a reason to abandon WinForms. There is an official path for adding Windows App SDK features to an existing WinForms app. 910
In other words, with WinForms you can choose:
- Keep the UI as it is
- Modernize only the Windows features you need
That is a realistic landing spot.
flowchart TB
accTitle: Modernizing while staying on WinForms
accDescr: Diagram showing that wanting the Windows App SDK is no reason to abandon WinForms, since keeping the UI as it is and modernizing only the required Windows features is a realistic landing spot.
g1["Want to use the Windows App SDK"] --> g2["No need to abandon WinForms"]
g2 --> g3["Keep the UI as it is"]
g2 --> g4["Modernize only the needed features"]
g3 --> g5["A realistic landing spot"]
g4 --> g5
Figure 9: WinForms can keep its UI and still modernize just the Windows features it needs.
5.2 WPF
Seen as the .NET UI for the Windows desktop, WPF is the best-balanced core. 4
Its strengths are clear.
- Screens can be written declaratively in XAML
- Data Binding is strong
- Styles / Templates are available
- Commands are available
- Easy to separate views from logic
- Easy to organize medium-to-large screen counts
The official WPF documentation describes data binding as a central WPF feature, and commands as a mechanism that separates input from execution logic. 67
So it suits projects such as:
- Business applications with many screens
- Lots of lists, details, editing, search, and status displays
- Windows applications maintained by multiple people over a long period
- Wanting to separate views from logic
- Wanting appearance and behavior responsibilities separated for future rework
- Screens that would quickly become heavy in WinForms
When in doubt on a new Windows-only business application, WPF is still the safe first candidate. Dismissing it with “WPF is old, so no” is a bit crude.
flowchart TB
accTitle: The safe first candidate for a new business app
accDescr: Diagram showing that for a medium-to-large Windows business application with many screens, a wish to separate View from logic, and long-term maintenance by several people, WPF is still the safe first candidate.
j1["Business app with many screens"] --> j4["WPF is the safe first candidate"]
j2["Want to separate View from logic"] --> j4
j3["Maintained long term by several people"] --> j4
j4 -.-> j5["Dismissing it as old is too crude"]
Figure 10: For a new business application with many screens and a long maintenance life, WPF is the safe first candidate.
On the contrary, if:
- You have existing WPF assets
- You have existing XAML / MVVM expertise
- Fluent is not your absolute top priority
- But you want a more cleanly designed UI than WinForms
then it is perfectly common for WPF to be the soundest approach.
Of course, WPF has its quirks too.
- Overwrought XAML becomes hard to read
- Piling up custom controls and templates makes maintenance heavy
- Leaning too far into a “solve everything with Binding” policy actually makes the flow of processing harder to follow
These are real, but they say less that WPF is bad and more that expressive tools swing back hard when swung carelessly.
WPF can also adopt parts of the Windows App SDK. That is, there is a path to modernize Windows features while staying on WPF. 810
For this reason, rather than
- Throwing away all of WPF for a wholesale WinUI migration
the approach of
- Bringing WPF up to current .NET
- Adding only the needed Windows features via the Windows App SDK
- Cleaning up the structure starting with major new features
wins more often in practice.
flowchart TB
accTitle: Incremental steps beat a full WPF migration
accDescr: Diagram showing that bringing WPF up to current .NET, adding only the required Windows features through the Windows App SDK, and reorganizing the structure starting from large new features wins more often in practice than discarding WPF for a full WinUI migration.
z1["Bring WPF up to current .NET"] --> z2["Add only the needed features via the SDK"]
z2 --> z3["Reorganize starting from large new features"]
z3 -.-> z4["Wins more often than a full migration"]
Figure 11: For WPF, incremental steps toward current .NET plus added features beat a full migration.
5.3 WinUI
WinUI is the modern front-runner when building a new, Windows-only application. 12
Officially, it is positioned as:
- Optimized for the latest hardware and input
- High DPI
- Smooth animation
- Part of the Windows App SDK
That is the official positioning. 1
So it suits projects such as:
- A new Windows-only product
- Where the UI’s impression and experience themselves matter
- Wanting to use Fluent straightforwardly
- Wanting to align with where Windows 11 is today
- Building on new windowing APIs and the latest Windows experience
Projects with a genuinely good reason to choose WinUI are generally not “it looks new” projects but “we want to bring today’s Windows experience into the product” projects.
flowchart TB
accTitle: How to tell a real reason for choosing WinUI
accDescr: Diagram showing that projects with a genuine reason to choose WinUI are not the ones that want a new look but the ones that want to bring today's Windows experience into the product.
y1["A project with a real reason for WinUI"] --> y2["Not because the look is new"]
y2 --> y3["But to bring today's Windows experience in"]
y3 -.-> y4["A new Windows-only product where UI impression matters"]
Figure 12: The reason to adopt WinUI is not newness but bringing today’s Windows experience in.
That said, there are caveats.
5.3.1 WinUI Is Not “Just a Newer WPF”
It looks close because it uses XAML, but the following differ:
- The underlying APIs
- The controls landscape
- Project structure
- The deployment / packaging mindset
- How you live with the Windows App SDK
In other words, thinking of it as a casual drop-in replacement for WPF is a bit risky.
flowchart TB
accTitle: WinUI is not just a newer WPF
accDescr: Diagram showing that although XAML makes WinUI look close to WPF, the underlying APIs, the controls, the project structure, the deployment and packaging mindset, and how you live with the Windows App SDK all differ, so treating it as a casual replacement for WPF is risky.
u1["Looks close because it uses XAML"] --> u2["But much of it differs"]
u2 --> u3["Underlying APIs and controls"]
u2 --> u4["Project structure and packaging"]
u2 --> u5["How you live with the SDK"]
u5 -.-> u6["Risky to treat as a casual replacement"]
Figure 13: Even with the same XAML, WinUI is not a casual drop-in replacement for WPF.
5.3.2 Choosing WinUI Pushes Deployment to the Foreground
WinUI 3 apps are packaged by default. Meanwhile, the Windows App SDK itself handles both packaged and unpackaged. 13142
What matters here is deciding early:
- How will you distribute it?
- How will the runtime be installed?
- Is package identity required?
- Internal distribution, the Store, MSIX, or the traditional EXE / MSI route?
Being told to “check early” without being told what to check is not very helpful, so here is what the check actually consists of.
First, there are two axes to settle. 1315
- packaging: whether the app has package identity
- runtime: whether the Windows App SDK is used framework-dependent or shipped self-contained
flowchart TB
accTitle: The two axes to settle first
accDescr: Diagram showing that WinUI deployment starts by settling two axes, the packaging axis of whether the app has package identity and the runtime axis of whether the Windows App SDK is used framework-dependent or shipped self-contained.
h1["Deployment design"] --> h2["The packaging axis"]
h1 --> h3["The runtime axis"]
h2 -.-> h4["Does it have package identity"]
h3 -.-> h5["Framework-dependent or bundled"]
Figure 14: For deployment, settle the packaging and runtime axes first.
There are three options on the packaging side. 13
| Model | package identity | Installer | Where it fits |
|---|---|---|---|
| packaged (MSIX) | Yes | MSIX replaces the installer | New development, Store publishing, enterprise distribution via Intune and similar |
| packaged with external location (sparse package) | Yes | Keeps using your existing installer | Existing Win32 / WPF / WinForms apps that already have their own installer |
| unpackaged | No | MSI / EXE / xcopy | Internal tools, broadly distributed traditional Win32 apps |
Next, decide whether package identity is required, working from the features. These are examples of features that the official documentation explicitly says do not work without package identity. 13
- Background tasks
- Push notifications (WNS)
- Share targets
- File Explorer context menu extensions
- File type and URI scheme associations
- Startup tasks
- App Service
- Windows AI APIs
In practice, run the check in this order.
- Derive it from the requirements. Do you plan to use any feature on the list above? Even one means you need the packaged side.
- See whether the existing installer can be dropped. If you do not want to drop it, the answer is packaged with external location, not a full migration to MSIX. Both the existing binary layout and the existing update mechanism stay as they are, and you add only the identity. 13
- Verify at run time. Whether a running process has identity can be determined with
GetCurrentPackageFullName. Without identity it returnsAPPMODEL_ERROR_NO_PACKAGE. Conversely, if calling a Windows API producesE_ILLEGAL_METHOD_CALLorAPPMODEL_ERROR_NO_PACKAGE, that is the sign you have hit a package identity requirement. 13 - Verify on the machine. The installed packages can be listed with the PowerShell
Get-AppxPackagecmdlet. - Decide the runtime last. If you want to distribute by xcopy or zip, self-contained is the default route; if you are publishing to the Store, framework-dependent is. 15
Deployment matters for WinForms / WPF too, but with WinUI it surfaces sooner. A new WinUI 3 app is packaged by default, so if you decide nothing, you are automatically on the MSIX route. 13 You thought you were choosing a UI, and it turns out you were choosing a deployment strategy - that is the slightly tricky part of this world.
flowchart TB
accTitle: Steps for checking package identity
accDescr: Diagram showing the five-step check of deriving from requirements which features need package identity, seeing whether the existing installer can be dropped, verifying at run time and on the machine, and deciding the runtime last.
s1["1. Derive from the requirements"] --> s2["2. Can the installer be dropped"]
s2 --> s3["3. Verify at run time"]
s3 --> s4["4. Verify on the machine"]
s4 --> s5["5. Decide the runtime"]
s2 -.-> s6["If not, use packaged with external location"]
s3 -.-> s7["Determine with GetCurrentPackageFullName"]
Figure 15: Check whether package identity is needed in this order: requirements, installer, run time, machine.
5.3.3 “Mixing WinUI Bit by Bit into Existing WPF / WinForms” - Experiment First
This is where expectations tend to balloon. However, Microsoft’s own FAQ says, in effect, that unless you are prepared to fully migrate your UI framework, you often cannot use WinUI. As for XAML Islands, the official documentation shows a path for embedding into existing desktop apps, while the Windows App SDK 1.4 release notes state that at present it has mainly been tested in C++ apps, and convenient wrapper elements for WPF / WinForms are not included. 1011
In other words:
- “Incremental migration looks feasible”
- “We can embed it piece by piece”
are attractive as concepts, but should be validated on a small scale before becoming a project’s main strategy.
WinUI is at its soundest when you are:
- Starting fresh
- Crafting an experience for a Windows-only product
Conversely, as a landing pad for wholesale replacement of existing WPF / WinForms, it needs justification and verification.
flowchart TB
accTitle: Validate incremental migration before making it the strategy
accDescr: Diagram showing that mixing in WinUI gradually is attractive as a concept, but the FAQ implies full migration is the premise and XAML Islands ships no convenient wrappers for WPF or WinForms, so it should be validated on a small scale before becoming the main strategy.
v1["Want to mix in WinUI gradually"] --> v2["Attractive as a concept"]
v2 --> v3["The FAQ assumes full migration"]
v3 --> v4["No wrappers for WPF / WinForms"]
v4 --> v5["Validate small before making it the strategy"]
Figure 16: Mixing in WinUI bit by bit should be validated on a small scale before it becomes the main strategy.
6. Common Decision Mistakes
6.1 “WinUI, Because It’s the Newest”
This is easy to understand, and quite risky.
The reason to choose a new technology should be judged on whether there is value obtainable only with that technology.
- Is the modern Windows experience the product value?
- Do you want to use Fluent straightforwardly?
- Is it a new product?
- Can you accept the deployment / operations prerequisites?
If these are yes, WinUI is a strong candidate. If the argument is merely “it seems future-proof,” the cost justification is weak.
flowchart TB
accTitle: Choose by value, not by newness
accDescr: Diagram showing that a new technology should be chosen on whether it delivers value obtainable no other way, that a yes makes WinUI a strong candidate, and that seems future-proof on its own is a weak cost justification.
q0["The reason for choosing a new technology"] --> q1{"Is there value obtainable only this way"}
q1 -->|"yes"| q2["WinUI is a strong candidate"]
q1 -->|"only seems future-proof"| q3["Weak cost justification"]
Figure 17: Choose on whether the technology delivers value obtainable no other way, not on newness.
6.2 “We Want the Windows App SDK, So We Must Use WinUI”
This is a common misunderstanding, and it is wrong.
The Windows App SDK can be added to existing WPF / WinForms apps. The official FAQ also clarifies that WPF / MFC / WinForms apps can use Windows App SDK APIs unrelated to WinUI. 1089
For example, features such as:
- App Lifecycle
- Windowing
- Toast Notifications
can in some cases be adopted while keeping your current UI. 10
6.3 “WPF / WinForms Are Already Dead”
Do not write these off casually either.
Both WinForms and WPF have ongoing documentation and migration paths on current .NET, and are officially treated as active Windows desktop UIs. 34
As evidence for a long-term maintenance decision, whether new features keep landing is a clearer indicator than “whether the documentation is still there.” Seen that way, here is where the three stand.
| Recent activity | How to read it | |
|---|---|---|
| WPF | .NET 9 added a Fluent theme for Windows 11, and the ThemeMode property switches between light, dark, and system. It also honors the Windows accent color 16 |
The “WinUI because the look is dated” argument is weaker than it used to be |
| WinForms | .NET 9 brought provisional dark mode support, switchable with Application.SetColorMode. Note that this is an experimental feature, with full support targeted at .NET 10. More async-capable APIs have also been added 17 |
New features are landing, but some of them come with an experimental flag |
| WinUI / Windows App SDK | Updates continue on a release cycle of its own, separate from .NET 18 | Updates are active, but you have to track them separately from the .NET version, which adds one more item to the maintenance plan |
For long-term maintenance, then, this reads as follows.
- WPF and WinForms are not “frozen and abandoned”; features arrive with each yearly .NET release. That said, some of the headline WinForms features are still at an experimental stage, so check the timing before you adopt them.
- Choosing WinUI means managing the .NET support deadline and the Windows App SDK support deadline separately. On long-running projects, that quietly adds up.
- Whatever you choose, nothing guarantees “it still runs unmodified ten years from now,” so it is more practical to decide up front how far you will follow the versions.
flowchart TB
accTitle: How to read long-term maintenance
accDescr: Diagram showing that WPF and WinForms receive features by riding the yearly .NET releases while choosing WinUI means managing the .NET and Windows App SDK support deadlines separately, so decide up front how far to follow the versions.
m1["WPF / WinForms"] --> m2["Features arrive with .NET releases"]
m3["WinUI"] --> m4["Manage the SDK deadline separately"]
m2 --> m5["Decide up front how far to follow"]
m4 --> m5
Figure 18: For long-term maintenance, see what the updates ride on and decide the follow-along policy first.
Particularly for business applications, the following routinely outweigh the newness of the UI framework:
- Existing assets
- Third-party controls
- Screen count
- Reports and printing
- Device integration
- Deployment procedures
6.4 “Might As Well Do a Full Rewrite”
A full rewrite is closer to a business decision than a technology choice.
If an existing application exists, the first things to examine are:
- What is actually causing the pain?
- Is it a UI problem or an architecture problem?
- Are dependent DLLs / COM / OCX / reporting / deployment the real burden?
- Can the pain be solved without replacing the entire UI?
A UI rewrite is flashy, but so is its cost. And even with a new look, the surrounding complications mostly remain.
flowchart TB
accTitle: Four questions before a full rewrite
accDescr: Diagram showing that a full rewrite is closer to a business decision than a technology choice, so first ask what really hurts, whether it is a UI or an architecture problem, whether dependencies and deployment are the real burden, and whether the pain can be solved without changing the UI.
r1["1. What really hurts"] --> r2["2. UI or architecture"]
r2 --> r3["3. Are dependencies or deployment the burden"]
r3 --> r4["4. Can it be solved without changing the UI"]
r4 -.-> r5["A rewrite is flashy in cost too"]
Figure 19: Before deciding on a full rewrite, pin down what the pain really is with four questions.
6.5 “XAML Islands Will Sort It Out Later”
The hope is understandable. But it is safer not to treat it as a lifeboat from the outset. 1011
For incremental migration, first try out, on a small scale:
- Which controls do you want to embed?
- What happens to focus, input, DPI, and theming?
- Does that hosting configuration actually remain stable?
flowchart TB
accTitle: Try XAML Islands small first
accDescr: Diagram showing that incremental migration should first test on a small scale which controls need embedding, what happens to focus, input, DPI, and theming, and whether the hosting configuration stays stable, rather than treating XAML Islands as a lifeboat from the outset.
p0["The hope that it will work out later"] --> p1["Which controls need embedding"]
p0 --> p2["Focus, input, DPI, theming"]
p0 --> p3["Is the hosting configuration stable"]
p1 --> p4["Try it small first"]
p2 --> p4
p3 --> p4
Figure 20: Do not treat XAML Islands as a lifeboat; test those three points on a small scale first.
7. How to Look at Things When an Existing App Is the Premise
This matters more for existing apps than for new ones.
7.1 If You Have Existing WinForms
Before leaping to WinUI, check these first.
- Can it be brought up to current .NET?
- Is 64-bit migration needed?
- Can async / await, exception handling, settings, and logging be cleaned up?
- Can maintainability be raised by splitting screens or extracting UserControls?
- Can the needed Windows features be added via the Windows App SDK alone?
What looks like a WinForms problem is, not infrequently, actually just:
- Screens and logic mixed together
- Sloppy thread boundaries
- Settings / files / COM / DB responsibilities crammed together
In that case, moving to WinUI only renames the problem and keeps it.
flowchart TB
accTitle: The problem survives under a new name
accDescr: Diagram showing that what looks like a WinForms problem is often a structural one, with screens mixed into logic, sloppy thread boundaries, and crammed responsibilities, in which case moving to WinUI only renames the problem.
e1["Looks like a WinForms problem"] --> e2["Actually a structural problem"]
e2 --> e3["Screens and logic mixed together"]
e2 --> e4["Sloppy thread boundaries"]
e2 --> e5["Crammed responsibilities"]
e4 --> e6["Moving to WinUI only renames it"]
Figure 21: A structural problem that looks like a UI problem survives a change of framework.
7.2 If You Have Existing WPF
WPF makes existing assets easy to leverage.
- XAML assets
- Binding
- Styles / Templates
- Commands
- MVVM
Any reason to throw these away should be quite explicit.
For example:
- You want a complete product UI overhaul
- You want Fluent as the main axis
- You are carving out a new module as a separate product
- You want to move toward a new experience as a Windows-only product
These are reasons to consider WinUI. But a bare “because WPF is old” is weak.
7.3 What Is Truly Heavy Is Usually Not the UI
In practice, the painful parts are, surprisingly often, these:
- ActiveX / OCX
- COM interop
- Custom reporting
- Printing
- Excel / Office integration
- Native DLLs
- 32-bit / 64-bit mismatches
- Installers, permissions, updates, signing
Take these lightly and even a beautified UI will not lighten the project as a whole.
So for migrating an existing app, take stock of the dependency boundaries as a whole rather than looking at the UI framework alone, and do that first.
flowchart TB
accTitle: Take stock of the dependency boundaries
accDescr: Diagram showing that what is truly heavy in practice is usually outside the UI, such as ActiveX and COM, reporting and printing, native DLLs, and installers and updates, so taking stock of the dependency boundaries comes before looking at the UI framework.
d1["ActiveX / COM interop"] --> d4["What is truly heavy is not the UI"]
d2["Reporting, printing, Office integration"] --> d4
d3["Installers, permissions, updates, signing"] --> d4
d4 --> d5["Take stock of dependency boundaries first"]
d5 -.-> d6["A beautified UI alone does not lighten it"]
Figure 22: What is truly heavy in a migration is the non-UI dependencies, so take stock of them first.
8. The Final Five Questions When You Are Stuck
If you are still stuck at the end, apply these five questions in order.
8.1 Are the Existing Assets Large?
- Large -> Basically preserve the existing lineage
- Small / none -> Move on to selecting for new development
8.2 Is a “Modern, Windows-Native Experience” Mandatory for This App?
- Mandatory -> WinUI is a strong candidate
- Not really -> Check whether WPF / WinForms suffices
8.3 Are the Screens Standard-Form-Centric, or Do They Need XAML-Style Expressiveness?
- Standard-form-centric -> WinForms
- Styles / templates / Binding / MVVM matter -> WPF
8.4 Do You Want a Full UI Overhaul, or Added Windows Features?
- Full UI overhaul -> Consider WinUI
- Just added features -> Consider current WPF / WinForms + Windows App SDK first
8.5 Can You Explain Deployment / Updates / Operations Up Front?
- Still vague -> For WinUI, nail down packaging / deployment early
- Want to ride existing operations heavily -> WPF / WinForms usually has less friction
flowchart TB
accTitle: The flow of the final five questions
accDescr: Diagram showing how the questions of whether existing assets are large, whether a modern experience is mandatory, whether the screens are standard-form-centric or need expressiveness, and whether deployment and operations can be explained narrow the options in order.
f1{"Are the existing assets large"} -->|"Large"| f2["Preserve the existing lineage"]
f1 -->|"Small or none"| f3{"Is a modern experience mandatory"}
f3 -->|"Mandatory"| f4["WinUI is a strong candidate"]
f3 -->|"Not really"| f5{"Standard-form-centric"}
f5 -->|"Yes"| f6["WinForms"]
f5 -->|"Expressiveness matters"| f7["WPF"]
f2 -.-> f8["If only adding features, look at the SDK first"]
f4 -.-> f9["Nail down packaging and deployment early"]
Figure 23: When stuck, narrow it down by asking about existing assets, experience, and the nature of the screens in that order.
These five questions narrow things down considerably. Summed up bluntly at the end:
- Internal forms built fast -> WinForms
- A long-lived Windows business application -> WPF
- A new, modern Windows product UI -> WinUI
- Keeping what you have and modernizing only the Windows features -> Current framework + Windows App SDK
9. Summary
Choosing among WinForms, WPF, and WinUI is not a game of sorting by age and picking the rightmost one.
The first things to look at are these four.
- Where are the existing assets?
- Are the screens form-centric or expressiveness-centric?
- Is a modern, Windows-native UI a product requirement?
- How will deployment / updates / operations be run?
Once these four are visible, the direction mostly decides itself.
flowchart TB
accTitle: The four questions in the summary
accDescr: Diagram showing that once where the existing assets are, whether the screens are form-centric or expressiveness-centric, whether a modern UI is a product requirement, and how deployment and operations will be run are all visible, the direction mostly decides itself.
n1["Existing assets"] --> n5["The direction mostly decides itself"]
n2["The nature of the screens"] --> n5
n3["Modern UI requirement"] --> n5
n4["Deployment and operations"] --> n5
Figure 24: Once the four questions are answered, the framework direction mostly decides itself.
- A large existing WinForms estate -> first, stay on WinForms
- A large existing WPF estate -> first, stay on WPF
- New and standard-form-centric -> WinForms
- New, medium-to-large Windows business application -> WPF
- New, where the modern Windows experience is itself the requirement -> WinUI
- If you only want the Windows App SDK, do not jump everything to WinUI at once
What we most want to avoid are these three:
- Discarding something because it is old
- Choosing something because it is new
- Starting on “it’ll work out somehow along the way”
The Windows desktop is a world where assets, deployment, operations, and dependencies weigh more than looks. So it is more practical to favor the choice with the least friction against existing assets, deployment, and operations, rather than the one with the most novelty.
10. References
-
Microsoft Learn, “WinUI 3 - Windows apps” / Microsoft Learn, “Modernize your desktop apps for Windows” ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Microsoft Learn, “What is Windows Forms - Windows Forms” ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, “What is Windows Presentation Foundation - WPF” ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, “What is Windows Forms Designer?” ↩ ↩2
-
Microsoft Learn, “Data binding overview - WPF” ↩ ↩2 ↩3
-
Microsoft Learn, “Commanding Overview - WPF” ↩ ↩2 ↩3
-
Microsoft Learn, “Use the Windows App SDK in a WPF app” ↩ ↩2 ↩3
-
Microsoft Learn, “Use the Windows App SDK in a Windows Forms (WinForms) app” ↩ ↩2 ↩3
-
Microsoft Learn, “Windows developer FAQ” ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
Microsoft Learn, “Windows App SDK 1.4 release notes” / Microsoft Learn, “Windows App SDK” ↩ ↩2 ↩3
-
Microsoft Learn, “Windows data binding and MVVM” ↩
-
Microsoft Learn, “Packaging overview - Windows apps” / Microsoft Learn, “Grant package identity by packaging with external location” ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Microsoft Learn, “Quick start: Set up your environment and create a WinUI 3 project” ↩
-
Microsoft Learn, “Package and deploy Windows apps overview” ↩ ↩2
-
Microsoft Learn, “What’s new in WPF for .NET 9” ↩
-
Microsoft Learn, “What’s new in WinForms for .NET 9” ↩
-
Microsoft Learn, “Windows App SDK release channels” ↩
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
Windows App Outsourcing and Custom Software Development: What to Sort Out Before You Ask
Before commissioning Windows app outsourcing or custom software development, here is how to sort out existing software modification, devi...
What "Not Responding" Really Is — How Windows Decides an App Has Hung, and How to Design Apps That Don't
Windows' "Not Responding" is a mechanism in which the OS judges that a window has not retrieved a message for 5 seconds and replaces it w...
CI/CD for WinForms / WPF Apps in Practice — Automating from Build to Signing and Distribution with GitHub Actions
A practical guide to setting up CI/CD for WinForms / WPF apps with GitHub Actions. Covers a minimal YAML for build+test on windows-latest...
System Tray Icons and Toast Notifications in Windows Apps — NotifyIcon Pitfalls and Choosing the Right AppNotification API
A practical guide to keeping a business Windows app resident in the system tray and notifying users with toast notifications. Covers the ...
Why Use the .NET Generic Host and BackgroundService in Desktop Apps
How to use the Generic Host and BackgroundService to organize startup, periodic processing, shutdown, logging, configuration, and DI in W...
Related Topics
These topic pages place the article in a broader service and decision context.
Windows Technical Topics
Topic hub for KomuraSoft LLC's Windows development, investigation, and legacy-asset articles.
UI Threading & Timers
Topic page for WPF / WinForms UI threading, async flow, Dispatcher usage, and timer decisions.
Where This Topic Connects
This article connects naturally to the following service pages.
Windows App Development
Choosing between WinForms, WPF, and WinUI is directly connected to new Windows desktop application development and to strategies for extending the life of existing assets.
Technical Consulting & Design Review
This topic fits the stage where you sort out which choice causes the least friction, taking into account existing assets, the Windows App SDK, deployment design, UI expressiveness, and MVVM culture.
Frequently Asked Questions
Common questions about the topic of this article.
- What is the difference between WinUI 3 and WPF?
- Both use XAML, but WinUI is not simply a newer WPF. The underlying APIs, the controls, the project structure, the deployment and packaging mindset, and the way you live with the Windows App SDK all differ. WPF is a UI framework for medium-to-large business applications, with resolution-independent vector-based rendering, data binding, styles and templates, and commands. WinUI is a modern UI framework that ships as part of the Windows App SDK and assumes Fluent, high DPI, and the latest Windows experience. Treating it as a casual drop-in replacement for WPF is risky.
- Should I choose WinForms, WPF, or WinUI for new development?
- It depends on the nature of the screens and on the product requirements. For a small-to-medium internal tool centered on standard controls and input forms that you want to build quickly, WinForms is still remarkably strong. For a medium-to-large business application with many screens where you want to make proper use of data binding, styles, templates, and MVVM, WPF is most often the safest choice. For a new Windows-only product where Fluent and a modern Windows experience are directly tied to product value, WinUI is a strong candidate. If your existing assets are large, start by assuming you continue on that lineage.
- Are WPF and WinForms already outdated?
- It is better not to write them off casually. Both WinForms and WPF have ongoing documentation and migration paths on current .NET, and Microsoft officially treats them as active Windows desktop UIs. For business applications in particular, existing assets, third-party controls, reporting and printing, device integration, and deployment procedures routinely outweigh the newness of the UI framework. Even for new development, it is not unusual for WinForms or WPF to be the choice with the least friction.
- Do I have to migrate to WinUI in order to use the latest Windows features?
- No. The Windows App SDK and WinUI are not the same thing: WinUI is the UI-framework part of the Windows App SDK. The SDK itself can be added to existing WPF, WinForms, and Win32 apps, and features such as App Lifecycle, Windowing, and Toast Notifications can in some cases be adopted while keeping your current UI. In other words, there is a path to modernize only the Windows features you need while staying on your existing WPF or WinForms UI, and a full UI migration is not mandatory.