VB6 Migration & Modernization

ModernLift · ·10 min read

Visual Basic 6 is a dead-end platform — its IDE has been unsupported since April 8, 2008, there is no supported way to build or maintain VB6 code, and Microsoft itself recommends replacing VB6 applications. The runtime is carried on supported Windows only for the lifetime of that OS and only for critical fixes. Migrating means moving the business logic onto a modern, maintainable platform, ideally slice by slice with each proven equivalent before cutover.

“Rewrite the VB6 app” sounds like a weekend project until you look at what the app actually is: a clutch of forms, a set of ActiveX and OCX controls, a runtime that ships with Windows almost by accident now, and a body of business logic the company has depended on for twenty years — much of it undocumented, written by people who are long gone. That’s why the rewrite is never as simple as it sounds, and why staying on VB6 is not a stable choice but a slowly closing one.

Where VB6 stands

Unlike a product with a single retirement date, VB6’s status is best read as a set of facts that all point the same way:

ComponentStatus
Visual Basic 6.0 IDEUnsupported since April 8, 2008
VB6 core runtimeCarried on supported Windows, lifetime of that OS, critical fixes only
Third-party OCX / ActiveX controlsNo Microsoft support
Building or maintaining VB6 codeNo supported method exists

These are Microsoft’s own support statements for Visual Basic 6.0. The runtime detail misleads people: yes, the core runtime files still ship with supported Windows, so existing apps keep running. But the support bar is limited to serious regressions and critical security issues, the development environment has been dead since 2008, and Microsoft explicitly recommends replacing VB6 applications. The line that matters is different from an ordinary end-of-life: there is nowhere to upgrade to. A VB6 app isn’t “old but fine” — it’s running on borrowed time on a platform with no future.

What staying on VB6 actually means

VB6’s dead-end status raises the stakes over an ordinary unsupported component, for three reasons.

  • The talent is disappearing. The pool of engineers who can safely change VB6 code shrinks every year. When the last person who understood the app retires, the application becomes a black box the business is afraid to touch.
  • The dependencies are crumbling. The ActiveX and OCX controls a VB6 app relies on are unsupported, often unavailable, and break on new Windows builds. Each Windows update is a roll of the dice.
  • It blocks the business. The app can’t integrate cleanly with modern systems, can’t move to the web or cloud, and can’t add the capabilities the business now needs. It’s not just risky — it’s a ceiling.

The COM and OCX problem

Most of the day-to-day pain of a VB6 app lives in its ActiveX and OCX controls, and it pays to be concrete about why they are so hard to carry forward. Any migration plan that hand-waves past them is underscoping the work.

  • They pin you to 32-bit. Classic COM controls are 32-bit, so the process that hosts them stays 32-bit. That caps addressable memory and blocks a clean 64-bit target until every last control is replaced.
  • They depend on registration. Each control has to be registered on the machine through regsvr32 and the registry. That makes installs brittle, breaks under least-privilege lockdowns, and turns “it works on my machine” into a real support cost.
  • Some are simply gone. Twenty-year-old grids, reporting controls, and communication libraries came from vendors that no longer exist. You may have no license, no source, and no supported replacement, only a binary that happens to still load today.
  • They assume an old world. Many controls were written against single-threaded apartment assumptions and old Windows behavior. New Windows builds and modern security defaults are exactly where they break.

This is why “just move it to .NET” is never only a language exercise. Every control is its own small migration: find a modern equivalent, reproduce its behavior, and prove the replacement matches before it carries live work.

The migration options

There is no single right move; there’s a right move for your application, and it turns on how much real business logic lives inside the VB6 code. Start with where the app should land, then decide how much of it is worth carrying there.

TargetBest fit whenThe honest tradeoff
Windows desktop on .NET (WinForms or WPF)The app must stay a rich desktop client with heavy local UI, printing, hardware access, or offline use, and the team is a Windows shopClosest shape to the original, so parity work is most contained. But you still own desktop deployment and you still have to design out every COM and OCX dependency. It is not a free ride to the web.
Web applicationUsers are distributed, you want central deployment, and the workflows suit a browserRemoves per-desktop installs and opens up integration with other systems, at the cost of the biggest change in behavior and UX, which makes the parity work heaviest.
Off-the-shelf softwareThe app does something a packaged product now does well, and the logic isn’t a differentiatorCheapest exit when it genuinely fits. But configuration and data migration are real work, and forcing a bad fit is worse than a rebuild.
Stay on the supported runtime, for nowSmall, stable, no compliance exposure, blocking nothingA legitimate short-term call. But the clock keeps running as talent, controls, and Windows changes all move against you.

Those are destinations. How much of the app you carry to one of them is the second decision:

  • Replace with off-the-shelf software where the VB6 app does something a packaged product now does well. The cleanest exit when the application’s logic isn’t actually a differentiator — why maintain custom code for a solved problem.
  • Rebuild on a modern platform when the logic is genuine intellectual property. The most common honest answer for a VB6 app, because there’s no supported in-place upgrade — the value is in the behavior, not the VB6 implementation, so the behavior is what you carry forward.
  • Re-express incrementally behind a facade rather than rebuilding everything at once. The same destination as a rebuild, but reached slice by slice so the application never goes dark and the undocumented behavior is captured as you go.

The decision is rarely about the language — VB6 has to go either way. It’s about what the application is actually worth keeping: the business logic, the rules, the workflows that took twenty years to get right. That’s what the migration is really protecting.

The automated upgrade trap

The tempting shortcut is a tool that promises to convert VB6 to VB.NET automatically. That covers the old Visual Basic Upgrade Wizard bundled with early Visual Studio, and the third-party transliterators sold as one-click ports. On a real twenty-year-old application it rarely ends well, and it helps to know why before you buy one.

  • It converts syntax, not behavior. These tools map VB6 statements to .NET equivalents almost line for line. Where the two languages differ, and they differ in ways that matter (default properties, Variant handling, fixed-length strings, control arrays, on-error flow), the output compiles but does not behave the same. Those gaps surface later as production bugs.
  • You inherit the same dead dependencies. A converter cannot replace an unsupported OCX or ActiveX control. It re-wires the translated code to the very controls you were trying to leave, so the new .NET project still cannot run without them.
  • The output is nobody’s code. A machine-translated codebase, littered with Upgrade_ warning comments and mechanical constructs, is often harder to maintain than the VB6 it came from. No one wrote it, no one understands it, and the undocumented business logic is now buried a layer deeper.

Automated conversion earns a place as a discovery aid. It can help read and map what the code does. Treating its output as the finished migration is a different thing, and it is how a “quick port” becomes a stalled rewrite. The value worth protecting is the behavior, and behavior is exactly what a transliteration does not prove.

How we modernize off it

A VB6 application doesn’t get rewritten in one risky pass. It gets modernized the way any legacy system does: small, reversible steps.

A strangler facade lets the legacy VB6 application and the modern path run side by side. We move one slice of behavior at a time — a form, a workflow, a calculation engine — and before any slice carries live work, we prove it behaves identically to the legacy: same results, same outputs, reconciled against the original. AI-accelerated discovery reads the forms, the modules, and the control dependencies end to end and captures what the code actually does — including the undocumented logic the original authors never wrote down, which on a twenty-year-old VB6 app is most of the risk — under senior-engineer review. Work shifts only on green, rollback stays a flag away, and the VB6 application is retired only once nothing depends on it.

Not every VB6 app is urgent

Not every VB6 app is a crisis. A small, stable internal tool that does one job, has no compliance exposure, and isn’t blocking anything can reasonably keep running on the supported Windows runtime for now — modernizing it tomorrow instead of today is a legitimate choice. And where a packaged product already does what the app does, buying beats rebuilding, and we’ll point you there rather than quote a build. The slice-by-slice rebuild earns its place when the VB6 app holds real business logic, when the dependencies are failing, or when it’s blocking what the business needs to do next. Matching the effort to the actual value is part of the assessment, not an afterthought.

Where to start

The first step is small and bounded: understand what the application is really worth before committing to a path. A discovery call scopes how much business logic lives in the VB6 code, which dependencies are at risk, what the app is blocking, and whether the right move is to replace, rebuild, or wait — on evidence, not a sales pitch. Reach the team at sales@modernlift.ai.

Frequently asked questions

Is VB6 still supported?
No, not in any meaningful way. The Visual Basic 6.0 IDE has been unsupported since April 8, 2008, so there is no supported method to create or maintain VB6 applications. The core VB6 runtime is shipped and supported on current Windows only for the lifetime of that OS, and only for serious regressions and critical security issues — third-party OCX and ActiveX controls get no support at all. Microsoft's own guidance is to replace VB6 applications with modern technology.
Why is VB6 a dead end rather than just old?
Because there is no path forward inside it. The IDE is unsupported, no new versions will ever ship, the developer pool shrinks every year, and the application depends on ActiveX and OCX controls that are themselves unsupported and increasingly hard to source. Unlike a version that is merely behind, VB6 has nowhere to upgrade to — the only forward direction is off it.
Can a VB6 application be migrated without a full rewrite?
Largely, when it is done incrementally. The business logic is preserved and re-expressed on a modern platform a slice at a time, with each slice proven to behave identically to the original before cutover, rather than transliterating line by line or rebuilding everything at once. The application keeps running throughout, and the undocumented behavior that VB6 apps are famous for is captured rather than lost.
Should I use an automated VB6 to VB.NET conversion tool?
Not as your migration strategy. The old Upgrade Wizard and the third-party transliterators sold as one-click ports convert syntax, not behavior, so on a real application the output compiles but does not run the same, and the differences show up later as production bugs. They also cannot replace unsupported ActiveX and OCX controls, so the converted project still depends on the very components you were trying to leave behind. The result is machine-generated code no one on the team wrote or understands. Automated conversion is useful as a discovery aid for mapping what the code does, not as the finished migration.
Should I migrate a VB6 app to .NET desktop or rebuild it as a web application?
It depends on how the app is used, not on fashion. A .NET desktop rebuild (WinForms or WPF) is the closest shape to the original and fits apps that need a rich local client, heavy printing, hardware access, or offline use. A web application fits when users are distributed, you want central deployment, and the workflows suit a browser, at the cost of the heaviest change in behavior and the most parity work. Either way you still have to design out the COM and OCX dependencies. The right target falls out of how much business logic lives in the code and how people actually use it, which is what a discovery call scopes.
Who provides VB6 migration services?
ModernLift provides VB6 migration services for US enterprises — re-expressing the business logic of a Visual Basic 6 application on a modern, maintainable platform without a big-bang rewrite. We work slice by slice and prove each migrated slice behaves identically to the original before it carries live work, so the application never goes dark. Senior engineers run the work, with AI-accelerated discovery mapping the forms, modules, and ActiveX/OCX dependencies — and the undocumented logic that is most of the risk on a twenty-year-old VB6 app.
How much does a VB6 migration cost?
There's no flat figure, because the cost tracks the application, not the language. The drivers are how much real business logic lives in the VB6 code, how many forms and workflows break into slices, the integration complexity around its ActiveX and OCX dependencies, and how much parity has to be proven before each cutover. Where a packaged product already does the job, buying beats rebuilding and we'll say so. The [legacy cost calculator](/legacy-cost-calculator) turns those inputs into a structured estimate.
How do I choose a VB6 migration company?
Look for a partner that scopes on evidence before quoting, proves parity rather than asserting it, and will point you to off-the-shelf software when that beats a rebuild. Ask specifically how they capture the undocumented business logic a VB6 app accumulates over twenty years — that, not the syntax, is where the risk lives. Our guide to [choosing a modernization vendor](/modernization-guides/application-modernization-vendors) walks through the criteria in depth.