Skip to content
Legacy Modernisation

WinForms to the Web: An AI-Assisted Rebuild Guide with Claude Code

14 min read

WinForms has no direct migration path to the web. Upgrading to .NET 10 keeps the application on the desktop, and conversion tools translate syntax without redesigning a desktop interaction model for the browser. The realistic routes are a rebuild with salvage or a strangler fig transition, and coding agents change the economics of both. They map event handlers, extract buried business rules, generate characterisation tests, and build the new ASP.NET Core front end against enforced architecture rules.

  • Decide the route first: rebuild with salvage, or strangler fig if the desktop must keep running.
  • The UI has to be rebuilt, but the business logic can usually be kept once it is extracted from code-behind and pinned by characterisation tests.
  • Keep the database schema stable during the rebuild, because it is your behavioural baseline.
  • Use guardrails (layer rules, hooks, and ArchUnitNET) so generated code cannot recreate the coupling you are escaping.

Our legacy application modernisation service covers desktop-to-web programmes end to end. For new builds and ongoing C# work, see our .NET development service.

Your WinForms application has run the business for fifteen years. Now it needs to be on the web

The application works, but only at desks, on Windows machines on the corporate network, where IT has installed it. The business now wants browser access, remote working, and integrations that the desktop model cannot offer. Meanwhile, the .NET Framework support clock is running underneath it.

This situation is common across UK mid-market estates, and it is structurally different from the .NET Framework version migration covered elsewhere in this cluster. A version migration moves the application to a newer platform and leaves its structure much as it was. A move from WinForms to the web changes how the application is structured and used, which is why the decisions in this guide differ from those in a version migration.

Why is there no direct WinForms to web migration path?

The desktop and web interaction models are incompatible, so better conversion tooling would not close the gap. WinForms is a stateful desktop model: the form lives in memory, event handlers mutate it directly, modal dialogs block, and multi-window workflows are normal. The web is request-based or component-based, stateless by default, and designed around navigation rather than windows.

Microsoft’s own guidance for the nearest comparable move (Web Forms to Blazor) makes clear that the UI layer is reconstructed rather than translated. Component vendors say the same for WinForms, and DevExpress’s migration guidance notes that data and business logic layers can be reused while the UI is rebuilt. Automated conversion products exist, and they can translate control trees into web components. They cannot tell you whether a screen-for-screen copy of a 2010 desktop workflow is what the business needs in a browser in 2026, and that question decides whether the result is any good.

Usually it is not what the business needs, because the rebuild is a chance to fix workflows that users have worked around for years. Treating the move as a conversion wastes that chance, and often produces a web application that feels like a desktop application squeezed into a browser tab.

Rebuild, convert, or strangler fig: how do you choose?

Two questions settle the route, in order: must the desktop keep running during the transition, and is the business logic separable from the UI? Where it is not, the rebuild has to recover the behaviour from the legacy code itself.

Choosing a WinForms to web migration route: strangler fig, rebuild with salvage, or rebuild with agentic archaeology
A decision flow for choosing a route for a WinForms application that needs to reach the web, with two questions and three outcomes, on the principle of choosing the route before choosing the framework. The first question is whether the desktop version must keep running during the transition. If it must, use the strangler fig route: extract logic behind APIs, move screens to the web module by module, and retire the desktop last. If not, the second question is whether the business logic is separable from the UI code-behind. If it is, rebuild with salvage: write characterisation tests first, then build a new ASP.NET Core front end over the salvaged services. If it is not, rebuild with agentic archaeology: extract the rules from the code-behind into a reviewed specification, then build fresh against it.

Strangler fig suits revenue-critical systems that cannot pause. The extracted business logic is exposed behind APIs, the desktop application is refactored to call them, and web screens replace desktop screens module by module. Incremental approaches like this ship value every sprint instead of at the end, at the cost of running two front ends for the transition period.

Rebuild with salvage suits applications where a cutover is acceptable and the logic layer is worth keeping. The UI is designed fresh for the web, and the business logic moves across behind characterisation tests.

Rebuild with agentic archaeology covers the hardest case, where business logic is so entangled with the UI, and so undocumented, that nothing can be ported directly. The legacy codebase then serves as the source of the specification, and none of its code is carried across. Agents extract the rules, people review them, and the new system is built against the reviewed specification. This mirrors the assess, map, extract-rules, transform, and validate workflow in Anthropic’s code modernisation playbook.

If you are still weighing modernisation against rebuild at the estate level, the modernise, rebuild, or replace framework covers that decision. This guide assumes the web is the destination.

What survives the rebuild? Salvaging business logic from code-behind

In a typical WinForms application, the most valuable code sits inside event handlers, which is the hardest place to reuse it from. Fifteen years of validation rules, pricing logic, and edge-case handling accumulate in btnSave_Click methods that also touch the UI and the database.

Salvage means extracting those rules into plain services that know nothing about forms or HTTP. The same logic can then serve the old desktop (in a strangler transition) and the new web front end.

C#
// BEFORE: WinForms code-behind. Validation, pricing, and data access
// entangled with the UI in one event handler.
private void btnSave_Click(object sender, EventArgs e)
{
    if (dtpDelivery.Value < DateTime.Today.AddDays(2))
    {
        MessageBox.Show("Delivery date must be at least 2 working days ahead.");
        return;
    }

    var discount = 0m;
    if (chkTradeCustomer.Checked && numQuantity.Value >= 50)
        discount = 0.12m;

    using var conn = new SqlConnection(connectionString);
    using var cmd = new SqlCommand(
        "INSERT INTO Orders (CustomerId, Quantity, Discount, DeliveryDate) " +
        "VALUES (@c, @q, @d, @dd)", conn);
    cmd.Parameters.AddWithValue("@c", (int)cboCustomer.SelectedValue);
    cmd.Parameters.AddWithValue("@q", (int)numQuantity.Value);
    cmd.Parameters.AddWithValue("@d", discount);
    cmd.Parameters.AddWithValue("@dd", dtpDelivery.Value);
    conn.Open();
    cmd.ExecuteNonQuery();
    MessageBox.Show("Order saved.");
}
C#
// AFTER: the rule extracted into a service that knows nothing about
// forms or HTTP. The same service serves web, API, and tests.
public class OrderService(IOrderRepository repository, TimeProvider timeProvider)
{
    public async Task<Result<Order>> CreateOrderAsync(
        CreateOrderRequest request,
        CancellationToken cancellationToken = default)
    {
        var earliestDelivery = timeProvider.GetUtcNow().Date.AddDays(2);
        if (request.DeliveryDate < earliestDelivery)
            return Result<Order>.Failure(
                "Delivery date must be at least 2 working days ahead.");

        var discount = request is { IsTradeCustomer: true, Quantity: >= 50 }
            ? 0.12m
            : 0m;

        var order = new Order(
            request.CustomerId, request.Quantity, discount, request.DeliveryDate);
        await repository.AddAsync(order, cancellationToken);
        return Result<Order>.Success(order);
    }
}

The web front end (a Razor Pages handler, an MVC controller action, or an API endpoint) becomes a thin adapter over that service. The legacy desktop form becomes one too, if it needs to keep running during a strangler transition.

Two disciplines make the salvage safe:

  • Characterisation tests before extraction. Pin the current behaviour with tests written against the legacy logic, including behaviour that looks like a bug. Every extraction has to keep those tests green, so any change in behaviour becomes a decision agreed with a product owner instead of an accident.
  • Keep the database schema stable. The data layer is the behavioural baseline for the whole exercise, so resist the temptation to fix the schema mid-rebuild. Database modernisation is its own workstream, covered in the .NET modernisation playbook.

How do coding agents change the economics of a desktop-to-web rebuild?

Full rebuilds have a bad reputation for good reasons: years of spend before any value, and a specification that existed only in the old code. Coding agents help with both problems, because the most expensive phases of a rebuild are the ones agents handle well.

Archaeology at scale. An agent can sweep every form and event handler in the solution and produce a structured inventory. It records which handlers contain business rules and which are pure UI plumbing, what each rule appears to do, and where the same rule is duplicated with variations. On estates with hundreds of forms, this turns weeks of reading into days of review. The output is a rules catalogue that people then verify with the business, screen by screen.

Characterisation tests without the drudgery. Agents generate the pinning tests against the extracted rules, and mutation testing confirms that the tests fail when the behaviour changes. Our AI test quality guide explains why coverage alone is misleading here.

Generation under guardrails. In our experience, the new front end and service layers are the kind of pattern-consistent code agents produce well, provided the harness stops them recreating the coupling you are escaping. We treat three things as the minimum set: layer rules enforced with ArchUnitNET, a PostToolUse hook that runs dotnet build after every edit, and an AGENTS.md carrying the rebuild rules. The harness engineering guide explains the model, and the .NET configuration guide has the copy-pasteable setup.

Design and UX at scale. On systems with large screen inventories, we use AI for the design and UX work as well. It generates a design system, screen layouts, and consistent interaction patterns across hundreds of screens. At that scale it is far more efficient than manual design. Consistency across the whole application comes from the approach itself, so reviewers do not have to enforce it screen by screen. People can then spend their time validating the redesigned workflows with the users who rely on them.

A rebuild-specific AGENTS.md looks like this:

Markdown
# Project: OrderDesk WinForms to web rebuild

## Target
- Source: WinForms on .NET Framework 4.8 (read-only reference at /legacy)
- Target: ASP.NET Core on .NET 10, Razor Pages
- Hosting: Azure Kubernetes Service (AKS)
- Database: existing SQL Server schema, unchanged

## Architecture rules
- Layers: Web -> Application services -> Domain -> Data access
- Web layer never references data access directly
- No SqlConnection/SqlCommand outside the data access project
- All rules from /docs/rules-catalogue.md implemented in Application services
- Every extracted rule keeps its characterisation tests green

## Do not
- Copy UI structure from the legacy forms
- Change database schema, table names, or column names
- Reimplement a rule that is not in the rules catalogue without flagging it
- Weaken or delete a characterisation test to make a build pass

The ‘read-only reference’ line is important. The legacy solution stays in the workspace so that agents can read it and check behaviour against it, but they should not copy code from it. Deny rules in .claude/settings.json can stop it from being edited.

Our AI Velocity Report publishes our own quarterly figures on how much production code agents author under this kind of harness.

Which web UI target should you choose?

Choose the target to fit the application’s interaction profile, rather than what the team is familiar with or what seems the default.

  • Razor Pages or MVC fit form-centric, page-at-a-time applications, which describes most internal WinForms line-of-business systems. Hosting and the state model are both simple, and developers with these skills are easy to hire.
  • Blazor Server fits teams that want richer interactivity while staying in C#. Plan for its connection behaviour, because every user holds a live circuit (a persistent connection to the server), which changes the operational profile compared with stateless pages.
  • React with a .NET API fits complex client-side interaction, an existing design system, or a product with external users. It also cleanly separates the API layer that a strangler transition needs anyway. Our BFF pattern guide covers how to structure that API layer.

A screen inventory usually shows that the application is a mix of things, for example eighty data-entry screens, a handful of complex interactive ones, and some reports. It is reasonable to serve those with different tools inside one application shell, instead of forcing everything through a single framework choice.

What does the delivery workflow look like?

The sequence below assumes the rebuild-with-salvage route. The strangler variant runs the same phases per module rather than per system.

  1. Assess and inventory. An agent sweeps the forms, event handlers, timers, integrations, and print paths, and produces a screen inventory, a draft rules catalogue, and an integration map. The legacy .NET assessment framework provides the scoring structure.
  2. Verify the rules catalogue with the business. It is cheapest to find out that a rule is obsolete, wrong, or contested before it is rebuilt. People carry out this step, and it is where decisions about workflow redesign are made.
  3. Pin behaviour with characterisation tests. Agents generate the tests against the catalogue, engineers review them, and mutation testing verifies them.
  4. Extract the service and data access layers. Salvage what is separable and reimplement the rest from the catalogue. ArchUnitNET rules lock the layering from the first commit.
  5. Build the web front end module by module. Group screens by workflow and build them against the services. Where modules are independent, parallel agents can work in separate worktrees (the scaling coding agents guide covers the context strategies).
  6. Run acceptance against the old system. Put the same inputs through both systems against the same data, and compare the outputs. Each difference should turn out to be either a defect or an improvement that has been agreed.
  7. Cut over, or retire the desktop module by module on the strangler route.

What about the database and the stored procedures?

Keep the schema stable through the rebuild, and treat database logic as a separate decision. Many WinForms estates carry significant business logic in SQL Server stored procedures. Some of it belongs in the new service layer, while some (set-based bulk work, for example) belongs where it is.

Our stored procedure modernisation guide covers the classify-then-move workflow in full. If Azure SQL is the eventual destination, run Microsoft’s assessment rules early, so compatibility issues come to light before they disrupt the plan.

What to watch for

State assumptions. Desktop code assumes the form stays alive between events, and web code cannot rely on that. Every piece of logic that reads ‘what the user did three clicks ago’ from control state needs an explicit decision about where that state lives: the page round-trip, the session, or component state.

Grid-heavy screens. WinForms grids handle editing, sorting, filtering, and clipboard behaviour that users rely on, often without anyone having specified it. Inventory the grid behaviours users depend on before choosing a web grid component, or the gaps will surface during user acceptance testing.

Printing, exports, and reports. A web application cannot send output straight to a printer the way a desktop application can. Every print path becomes a generated document or a job for a reporting tool, and each one should be captured as a requirement rather than treated as plumbing to port.

Long-running operations. Desktop applications block or spin up background workers, whereas the web needs job queues and progress patterns. Timers in forms (System.Windows.Forms.Timer doing polling or scheduled work) often hide integration logic that belongs in a background service.

Multi-window workflows. Users who work with three forms side by side will not accept a single linear page flow. Supporting it is an interaction design problem to solve as part of the rebuild, and porting the existing forms will not answer it.

Authentication and audit. On the desktop, Windows identity came for free. The web application needs an explicit identity design (typically Microsoft Entra ID for internal systems), and the rebuild is a good moment to add the audit trail the desktop version never had.

Security posture of generated code. A rebuild produces a large volume of new web-facing code quickly. The controls that prevent injection and cross-site scripting (XSS) vulnerabilities therefore need to be built into the harness through analysers, banned APIs, and review gates, rather than left to code review alone. The risks of AI-augmented development guide covers the control set.

Next steps

We recommend starting with the assessment before any debate about frameworks. The screen inventory, rules catalogue, and integration map determine the route, the sequencing, and a realistic cost, and an agent-assisted assessment produces them quickly.

Related guides in this cluster:

If you would like to look at your own estate, book a free consultation and we will talk through how a screen and rules inventory would work for your application.

Frequently asked questions

Can a WinForms application be converted to a web application automatically?
No. Conversion tools can translate individual controls and layouts, but the desktop interaction model (stateful forms, modal dialogs, and multi-window workflows) has no web equivalent, so the UI has to be redesigned and rebuilt. The business logic beneath the UI can usually be preserved, and that is where AI tooling helps most.
Should we target Blazor, Razor Pages, MVC, or React?
It depends on how the application is used and on your team. Data-entry applications map well to Razor Pages or MVC, and Blazor Server suits teams that want richer interactivity while staying in C#. React with a .NET API suits complex client-side interaction, or cases where a shared design system already exists. Choose against your requirements rather than assuming the Microsoft path is right.
Can the desktop application keep running during the move?
Yes, and for revenue-critical systems it usually should. A strangler fig approach exposes the extracted business logic behind APIs, moves screens to the web module by module, and retires the desktop application last. Both front ends run against the same services during the transition, so value ships incrementally instead of at the end.
How much of a WinForms to web rebuild can AI tooling do?
More than most teams expect, and that includes the design. Coding agents map event handlers, extract business rules buried in code-behind, generate characterisation tests, and build the new layers against enforced architecture rules. On large screen inventories we use AI for the design and UX work too, which is far more efficient than manual design at that scale. People still validate the workflows with users and review every change.
What happens to printing and reporting?
Desktop printing does not carry across. On the web it is replaced by server-generated documents (from a PDF generation library or a reporting service) delivered as downloads, or by moving reporting into a dedicated tool such as Power BI. Inventory every print and export path early, because they are easy to miss in an event-handler sweep and are often contractually required outputs.
Do we have to rewrite the database at the same time?
No, and usually you should not. Keeping the schema stable while the UI and application layers are rebuilt removes a whole class of risk, because the data provides the behavioural baseline. Database modernisation (moving business logic out of stored procedures, or migrating to Azure SQL) is better run as its own workstream once the new application layer is proven.
How long does a WinForms to web rebuild take?
It depends on screen count, how entangled the business logic is with the UI, and how much of the workflow should be redesigned rather than reproduced. We recommend a short assessment first, which inventories the screens, event handlers, and integrations so the estimate rests on evidence. Agentic tooling shortens the extraction and scaffolding phases, but it does not speed up the decisions the business has to make.

Ready to transform your software?

Let's talk about your project. Contact us for a free consultation and see how we can deliver a business-critical solution at startup speed.