VB6 and Legacy VB.NET Modernization
Visual Basic comes in two very different legacy forms. VB6 is a pre-.NET technology whose runtime Microsoft still supports for the life of supported Windows, but whose IDE and tooling have been unsupported since 2008, so VB6 code runs, but cannot be evolved with current tools. VB.NET runs on modern .NET and is fully supported, but Microsoft has frozen the language: it is stable and maintained, not evolving with new features. Modernizing either means the same thing. Extract the business logic into a clean, tested library, then rebuild the UI and entry points on a modern stack (typically C# on modern .NET), slice by slice with parity proven before cutover.
Beneath the WebForms and WCF layers, a surprising number of .NET estates carry code written in Visual Basic, sometimes VB6 components from before .NET existed, sometimes VB.NET that has run quietly on Framework for fifteen years. Visual Basic attracts more myth than any other corner of the Microsoft stack (“VB6 is dead,” “VB.NET is dead,” “you can’t run any of it anymore”), and most of it is wrong in ways that lead to bad decisions. This part sorts the facts from the folklore, then applies the series’ method.
Two different things called “VB”
The single most important step is to stop treating “Visual Basic” as one thing. There are two, and they sit on opposite sides of the .NET divide.
VB6 (Visual Basic 6.0) is a pre-.NET technology, a COM-based language and IDE from the late 1990s. It predates .NET Framework entirely. Apps built in it are typically Windows desktop applications or COM components.
VB.NET (now just “Visual Basic”) is a .NET language, the Visual Basic that runs on the .NET platform, a peer of C#. VB.NET apps on Framework are the same kind of apps as their C# siblings. They just use a different language.
Conflating the two produces nonsense plans, because their support stories and migration paths are completely different.
VB6 vs VB.NET at a glance
Before the plan, get the two straight. Almost every bad VB decision comes from applying a fact about one to the other. This table is the fastest way to keep them apart, and to see why the migration paths diverge.
| Dimension | VB6 | VB.NET |
|---|---|---|
| Era | Pre-.NET, COM-based, late 1990s | A .NET language, peer of C# |
| Runtime support | Supported for the life of supported Windows | Fully supported on modern .NET |
| IDE and tooling | Out of support since 2008 | Current Visual Studio |
| Language evolution | None, and never will | Frozen since 2020, stable but no new features |
| Typical app shape | Desktop app or COM component | Same app shapes as C# on .NET |
| Special boundaries | COM interop, forms UI with no direct port | Standard managed .NET |
| Migration path | Rebuild UI and entry points, logic lands in C# | Move to modern .NET, keep VB or convert to C# |
| Real risk | Unbuildable with modern tools, shrinking skills | Ecosystem momentum and hiring are all C# |
The accurate support picture
Here is what is actually true, stated precisely enough to repeat to a stakeholder:
- The VB6 runtime is supported. Microsoft supports the VB6 runtime for the lifetime of supported Windows releases, so VB6 applications continue to run on current Windows (Microsoft, Support Statement for Visual Basic 6.0). Your VB6 app is not going to stop launching next year.
- The VB6 IDE and tooling are not supported. The VB6 development environment has been out of support since 2008. You can run VB6 apps. You cannot build or maintain them with supported, current tools. That is the real problem: the code is effectively frozen because the only way to change it is with unsupported, increasingly hard-to-run tooling and an ever-smaller pool of people who remember it.
- VB.NET runs on modern .NET and is supported, but frozen as a language. In 2020 Microsoft stated it would keep Visual Basic stable rather than co-evolve it with C#. New language features go to C# only. So VB.NET code runs and is supported on modern .NET, but it will gain no new capabilities, and the ecosystem’s momentum, samples, libraries, and hiring are overwhelmingly C#.
VB6’s danger is not that it will stop running. It is that it has already stopped being maintainable. A runtime that works but cannot be safely changed is a business risk dressed up as a stable system.
Not all “VB” is VB6: VBA and VBScript
A quick clarification, because the wrong scope here wastes real money. When a stakeholder says “we have a lot of old VB,” they may not mean VB6 at all.
- VBA (Visual Basic for Applications) is the macro language embedded in Office, the code behind Excel workbooks, Access databases, and Word documents. It is still shipped and supported by Microsoft. An Access application with heavy VBA is a different modernization problem from a standalone VB6 app, even though the syntax looks similar.
- VBScript is the scripting language behind classic ASP pages and a lot of Windows automation. Microsoft has begun deprecating it, so it is on a genuinely different clock from the supported VB6 runtime.
They share a family resemblance, but they run in different hosts and have different futures. Scope each one on its own facts rather than treating “the VB stuff” as a single pile.
What actually drives the modernization
Because nothing is being switched off, the case for moving VB code is the same compounding one from Part 1, sharpened by two VB-specific facts:
- The maintenance pool is shrinking fast for VB6 and steadily for VB.NET. Finding engineers who can confidently change a VB6 codebase is hard and getting harder, which drives up cost and key-person risk.
- The knowledge is concentrated and undocumented. VB6 and early VB.NET apps were often built by small teams or single authors, and the rules they encode were rarely written down. When those people leave, the tribal knowledge leaves with them, and a system you cannot change and cannot understand is the worst combination in legacy software.
Stripe’s developer research put the cost of working around bad and poorly understood code at roughly 42% of developer time (Stripe, “The Developer Coefficient”). A frozen VB6 codebase that only a couple of people understand sits at the painful end of that distribution.
The method: extract first, rebuild second
Whether you are dealing with VB6 or VB.NET, the modernization follows the series’ loop, with one VB-specific emphasis: logic extraction comes first and matters most.
- Recover and extract the logic. VB6 and old VB.NET apps tend to bury business rules in form code and event handlers, exactly like Web Forms. The first job is to identify those rules and lift them into a clean, tested library. For VB6 especially, this often means reading the behavior out of the running system, because the source intent was never documented. Capturing it as a living specification is part of the work, not a side task.
- Rebuild the UI and entry points on a modern stack. A VB6 desktop app might become a web application or a modern .NET desktop app. A VB.NET Framework app moves onto modern .NET. The rebuilt surface calls into the extracted logic.
- Convert the language where it earns it. For VB.NET, you can keep the language (it runs on modern .NET) or convert to C#. Most teams convert during the rebuild to get the talent pool and ecosystem, and because the language is frozen, but it is a deliberate choice, not a mandate. For VB6, the logic is being rewritten anyway, so it lands in C# (or another modern language) naturally.
- Prove parity and cut over slice by slice behind a facade, the same as every other migration in this series. Each rebuilt slice is shown to match the original’s behavior before it carries load.
The order is the whole trick. Extracting and testing the logic before touching the UI means the rebuilt application stands on proven code, and the parity gate has a clean specification to check against, instead of trying to verify a rewrite against folklore.
The VB6 wrinkle: COM and the desktop
VB6 adds two complications that VB.NET does not, and they are worth naming so the plan accounts for them:
- COM interop. VB6 components often expose or consume COM interfaces, and other systems may bind to them. You cannot simply delete a COM component that something else calls. The incremental answer is the same facade idea applied at the component boundary: stand up the modern replacement, keep the COM surface working through interop or a thin shim until every caller has moved, then retire it. The callers migrate on their own schedule, not in a flag-day cutover.
- Desktop UI with no direct port. A VB6 forms application has no mechanical path to a modern UI. Like Web Forms, the screens are rebuilt. The destination is a product decision, a web application or a modern .NET desktop app, but the method is unchanged: extract the logic, rebuild the screen over it, prove parity, cut over.
Neither changes the strategy. They are reminders that VB6 sits a layer deeper in history than VB.NET, so its boundaries, COM in, forms out, need explicit handling rather than the assumption that everything is managed .NET code.
Triage by logic, not by age
A small VB6 utility or a tidy VB.NET service with logic already in libraries can move quickly, and converting VB.NET to C# is genuinely optional. Plenty of supported VB.NET runs happily on modern .NET. The heavy logic-recovery emphasis here is aimed at the apps that have become institutions: the VB6 system that runs a department, written by someone who retired, that nobody dares touch. For those, the recovery of the rules is the project, and skipping it is how a “simple rewrite” quietly drops behavior the business depended on. Triage by how much undocumented logic the code holds, not by its age.
Where this leads
Across Parts 2 through 5 the same phrase keeps recurring: tools can help with the mechanical parts, but the hard parts are rebuilt by hand. That deserves a straight answer. Part 6, .NET Modernization Tools: What They Do and Where They Stop, looks honestly at the Upgrade Assistant, the converters, and AI assistance, what they genuinely accelerate, and the line past which a tool cannot take you.
Frequently asked questions
- Is VB6 still supported?
- Partly, and the distinction matters. The VB6 runtime is supported by Microsoft for the lifetime of supported Windows releases, so VB6 applications continue to run on current Windows. But the VB6 development environment (the IDE and its tooling) has been out of support since 2008. So you can keep running VB6 apps, but you cannot build or maintain them with supported, current tools. That gap, running but unbuildable with modern tooling, is the real driver to modernize, not an imminent runtime shutoff.
- Is VB.NET dead?
- No, but it is frozen. VB.NET (now just "Visual Basic") is supported on modern .NET and Microsoft maintains it, but in 2020 Microsoft stated it would keep the language stable rather than evolve it with new features. New language capabilities go to C#. So VB.NET code runs fine on modern .NET and is supported, but it will not gain new language features, and most of the ecosystem's momentum, samples, and hiring pool are C#. Teams often migrate VB.NET to C# during modernization for those reasons, though it is not strictly required.
- Should we convert VB.NET to C#?
- Often, but it is a choice, not a requirement. VB.NET runs on modern .NET, so you can move the platform without changing the language. Teams convert to C# when they want the larger talent pool, the broader library and sample ecosystem, and a single language across the codebase, and because the language will not evolve further. The pragmatic approach is to extract logic into libraries first. That logic can be converted to C# as part of the rebuild, with parity proving the conversion did not change behavior.
- Is VB6 the same as VBA or VBScript?
- No, and confusing them leads to the wrong plan. VB6 is a standalone COM-based language and IDE for building desktop apps and components. VBA is the macro language embedded inside Office (Excel, Access, Word) and it is still shipped and supported by Microsoft. VBScript is a lightweight scripting language for classic ASP and Windows automation, and Microsoft has begun deprecating it. They share a family resemblance in syntax, but they run in different hosts and have different futures, so scope each one separately rather than lumping "the VB stuff" together.
- Can automated tools convert VB6 to modern .NET automatically?
- Not end to end. Converters and upgrade assistants genuinely accelerate the mechanical parts, syntax translation and project scaffolding, but they cannot recover undocumented business rules, redesign a forms UI that has no modern equivalent, or resolve COM boundaries other systems bind to. The reliable pattern is to use tools for the mechanical lift and rebuild the hard parts by hand under parity validation. Part 6 covers exactly where the tools help and where they stop.