The WPF Migration Paradox: Bridge or Rebuild?

OpenSilver just released version 3.3 with native Blazor integration - you can now embed Blazor components directly inside XAML applications. MudBlazor, Radzen, DevExpress - any Blazor component library works inside your existing WPF or Silverlight app.

It's technically impressive. Both XAML and Blazor render to the same DOM, share the same runtime, and use the same memory space. No JavaScript bridges. No iframes. Your ViewModels stay exactly the same.

But for teams with legacy WPF internal tools, this raises an uncomfortable question: should you bridge your existing app or rebuild from scratch?

The Bridge Appeal

The case for bridging is straightforward:

  • Your existing code works
  • Your team knows XAML
  • You can modernize incrementally - one component at a time
  • Risk is low because the app keeps running throughout

OpenSilver makes this genuinely viable. You don't have to rewrite your entire WPF application. You swap out individual components, test them, move on. The XAML layout model (Grid, StackPanel) stays, and your MVVM architecture is untouched.

For large applications with years of business logic baked in, this incremental approach makes sense.

The Hidden Cost

But bridging has a cost that's easy to underestimate: complexity accumulation.

Every bridged component means your app now speaks two languages. You have XAML components and Blazor components rendering side by side. New developers need to understand both systems. Debugging crosses framework boundaries. Your dependency tree doubles.

And the migration never finishes. There's always one more XAML component that's "not worth converting yet." Two years later, you have a hybrid app that's harder to maintain than either a pure XAML or pure web application.

When Clean-Slate Wins

For internal tools specifically - admin panels, data management interfaces, reporting dashboards - the math often favors starting fresh.

Internal tools have different economics than customer-facing products:

  • Users tolerate UI changes (they're your colleagues)
  • Feature parity isn't required on day one
  • Deployment simplifies massively (web vs. desktop installers)
  • Mobile access becomes free

Ivy is designed for exactly this scenario. Instead of migrating WPF controls to Blazor equivalents, you describe your data model and get a working web interface.

Here's a common WPF pattern - a master-detail view for entity management:

var db = UseService<AppDbContext>();
var selected = UseState<int?>(() => null);

return Layout.Vertical()
    | Text.H1("Equipment Tracker")
    | db.Equipment.ToDataTable(e => e.Id)
        .Header(e => e.Name, "Name")
        .Header(e => e.Status, "Status")
        .Header(e => e.LastInspection, "Last Inspection")
        .Config(c => {
            c.AllowSorting = true;
            c.AllowFiltering = true;
        });

No XAML Grid definitions. No DataGrid column templates. No INotifyPropertyChanged. The DataTable handles sorting, filtering, and rendering.

State management uses UseState hooks instead of MVVM:

var searchTerm = UseState("");
var statusFilter = UseState("all");

return Layout.Vertical()
    | searchTerm.ToTextInput(placeholder: "Search equipment...")
    | new Button("Clear", onClick: _ => {
        searchTerm.Set("");
        statusFilter.Set("all");
    });

If you've spent years writing ViewModels and ICommand implementations, this feels almost suspiciously simple. But for internal tools, that simplicity is the point.

The Decision Framework

Bridge when:

  • Your WPF app has complex, validated business logic that's risky to rewrite
  • The app is customer-facing and UI continuity matters
  • Your team is deeply invested in XAML and MVVM patterns
  • You have 50+ screens and years of edge case handling

Start fresh when:

  • The app is an internal tool used by your own team
  • The business logic lives in your database and APIs, not in the UI layer
  • You want web deployment, mobile access, or multi-user collaboration
  • The current WPF app is 5-10 screens of CRUD operations

Most internal WPF tools fall into the second category. The business logic is in stored procedures, API services, or database constraints. The WPF layer is just rendering forms and grids - exactly what modern frameworks can scaffold automatically.

The Takeaway

OpenSilver's Blazor integration is genuine engineering achievement. For teams with large, complex WPF applications, incremental migration is now a real option.

But for the common case - internal tools that display data, accept input, and manage records - bridging frameworks adds complexity you don't need. A clean-slate approach with purpose-built tooling gets you to a modern web app faster than migrating XAML one control at a time.

Explore Ivy if you're evaluating the rebuild path for internal WPF tools.

Want to try Ivy? Check out the GitHub repo or join our Discord community.

⭐ If you found this useful, a star on GitHub goes a long way — it helps more .NET developers discover Ivy.

Renco Smeding

Written by

Renco Smeding