VB6 to .NET migration — a practical guide
If your business still runs on a Visual Basic 6 application, you already know it works. You also know the IDE hasn't been supported since 2008, the developers who wrote it are retiring or gone, and every Windows update is a small roll of the dice. This guide walks through how to actually move a VB6 system to .NET — the strategy choices, the real cost and timeline numbers, the risks nobody mentions until they hit one, and how to staff the team that does it.
In this guide
- 1. Why VB6 migration can't wait until it breaks
- 2. Three migration strategies, and when to use each
- 3. Choosing your .NET target
- 4. Assessment: know what you're actually migrating
- 5. A phased approach that doesn't stop the business
- 6. Risks, and how to de-risk each one
- 7. What it actually costs and how long it takes
- 8. The skills your migration team needs
- 9. How to hire the team
- 10. Why an India-based team fits this work
- 11. Frequently asked questions
1. Why VB6 migration can't wait until it breaks
Visual Basic 6 shipped in 1998. Microsoft ended mainstream support for the IDE in 2005 and extended support in 2008. That means for close to two decades, nobody at Microsoft has fixed a bug in the VB6 development environment, patched a security hole in the compiler toolchain, or added a single feature. If you're still building or maintaining VB6 code today, you're doing it with tools frozen in the Bush administration.
The runtime is a separate story, and it's the one that keeps people complacent. msvbvm60.dll, the VB6 runtime, still ships in Windows 11 and still runs compiled VB6 applications. Microsoft has committed to keeping it there "for the supported lifetime of the operating system" — but that phrase has no fixed end date attached to it, and it has already caused real pain. Users have reported VB6 apps breaking or behaving differently after specific Windows 11 feature updates, particularly anything touching COM registration, UAC behavior, or 64-bit process boundaries. Nobody at Microsoft is testing VB6 compatibility against new Windows builds; you find out it broke when your users do.
Three pressures are converging at once, and none of them are hypothetical:
- Runtime risk compounds every year. Each Windows feature update is a small, uncontrolled experiment on whether your VB6 app still works. You have no support ticket to file if it stops.
- Security exposure has no fix path. VB6 predates modern .NET security features — sandboxing, code access security, built-in cryptography libraries that get patched. If a vulnerability turns up in how a VB6 app handles input, there's no vendor patch coming. You either work around it in application code or live with it.
- The talent that can maintain VB6 is disappearing. A developer who was mid-career writing VB6 in 2005 is now in their late 50s or 60s. Nobody has learned VB6 as a first language in 15 years. Every year you wait, the pool of people who can safely touch this codebase gets smaller and more expensive.
None of this means your app breaks tomorrow. It means the cost of migrating goes up, not down, the longer you wait — and the choice slowly stops being "when do we modernize" and starts being "who do we call when it's already broken."
2. Three migration strategies, and when to use each
There isn't one right way to move off VB6. There are three, and picking the wrong one for your app's size and complexity is the single most common way these projects go over budget.
| Strategy | Best for | Trade-off |
|---|---|---|
| Full rewrite | Apps with tangled, undocumented logic, or ones you want to redesign anyway | Highest cost and time, but you get clean, maintainable code and can fix long-standing design problems in the same pass |
| Automated conversion | Simple forms-and-data apps with little COM or custom control usage | Fast and cheap upfront, but the output is usually "VB6 logic wearing a C# costume" — it compiles, but nobody wants to maintain it long-term |
| Rehost / wrap | Apps under time pressure that need to survive one more OS cycle before a real rewrite | Cheapest and fastest, but it's a delay, not a fix — you still owe the real migration later, likely at a higher cost |
In practice, most mid-size and large VB6 systems end up as a hybrid: an automated tool handles the mechanical conversion of forms and simple data-bound controls, while a developer rewrites the business logic by hand — the calculations, the validation rules, the parts of the app where the actual value of the business lives. Treating the whole app as one strategy usually wastes money in one direction or the other.
3. Choosing your .NET target
Two decisions here, and they're independent of each other: which .NET runtime, and which UI framework.
.NET Framework 4.8 vs. modern .NET (8, 9, and onward): .NET Framework 4.8, released in 2019, is the last version of the old .NET Framework line. It still gets security patches. It gets no new features, ever, and it only runs on Windows. Modern .NET (what Microsoft just calls ".NET" now, on its annual release cadence) is where active development happens — better performance, cross-platform support, and a faster path to newer language features. If you're already paying for a migration, moving straight to modern .NET usually beats landing on .NET Framework 4.8 and paying for a second migration in three or four years. The one legitimate reason to stop at .NET Framework 4.8: a COM dependency or third-party control with no modern-.NET equivalent yet.
WinForms vs. WPF vs. web vs. Blazor: If your VB6 app is a desktop line-of-business tool and your users are fine with a desktop tool, WinForms in .NET is the closest like-for-like move, and the layout model plus event-driven pattern will feel familiar to whoever maintains it. WPF gives you more modern UI capability (data binding, styling, better multi-monitor and DPI handling) at the cost of a steeper learning curve for anyone new to it. If there's any appetite to get users off installed desktop software entirely, a web front end or Blazor (which lets a .NET team write UI in C# instead of switching to JavaScript) opens the door to browser access, no-install deployment, and easier future updates, though it's a bigger scope than a like-for-like port and it changes the UX your users are used to.
There's no universally correct answer. A 40-form internal tool used by six accountants doesn't need a web rewrite. A customer-facing app that IT has been begging to get off desktop installs for five years probably does.
4. Assessment: know what you're actually migrating
Every VB6 migration that goes over budget has the same root cause: someone estimated the work without actually looking at all of it. Before you write a line of C#, run a proper assessment. It typically covers four areas.
- Code inventory. How many forms, modules, and class modules exist? How many lines of code, and how is complexity distributed — is most of the logic in a handful of forms, or spread evenly across two hundred of them? This alone tells you whether you're looking at a 6-week project or a 6-month one.
- Dependency mapping. What does the app talk to — databases, file shares, printers, other internal systems, external APIs? Each integration point is a place the migration can quietly break something nobody tested.
- COM and ActiveX audit. This is usually where the real cost hides. List every third-party ActiveX control and every COM component the app references. Some have direct .NET equivalents. Some vendors went out of business a decade ago and their control has no replacement — those need a custom-built substitute, and that work is rarely trivial.
- Business logic extraction. Read through the code (not just the database) for rules that live only in the application: discount calculations, approval workflows, validation exceptions written for one specific customer three years ago. VB6 apps built over 15–20 years accumulate this kind of logic in event handlers where nobody would think to look for it, and it rarely has a comment explaining why it's there.
Budget real time for this phase — for a mid-size application, one to three weeks with someone who reads both VB6 and C# fluently. Skipping it to "save time" is the single most common reason migration estimates end up wrong by 50% or more.
5. A phased approach that doesn't stop the business
For anything beyond a small app, migrating everything at once in a "big bang" cutover is high-risk. The business keeps running on VB6 until one day it switches entirely to .NET, and if something's wrong, you find out in production with no fallback. A phased, strangler-style approach spreads that risk out.
Phase 1: Wrap and stabilize
Get the existing VB6 app running reliably on current hardware and OS versions, and put basic monitoring or logging around it if it doesn't have any. You want a stable baseline to migrate away from, not a moving target.
Phase 2: Migrate one module
Pick a self-contained business capability, such as reporting, a specific data-entry workflow, or an integration, and rebuild just that piece in .NET. COM interop lets the new .NET module talk to the remaining VB6 code while the migration is in progress, so you're not choosing between "all VB6" and "all .NET" on day one.
Phase 3: Run parallel, then cut over
Run the new .NET module alongside the old VB6 path for a defined period, comparing outputs on real data. Once the new module has proven itself on real transactions, route users to it and retire the equivalent VB6 code.
Phase 4: Repeat, then retire the shell
Move to the next module and repeat the cycle. Once every capability has moved, decommission the remaining VB6 shell — by this point it's an empty wrapper, not the system of record.
This takes longer in calendar time than a big-bang rewrite. It also means the business never stops functioning during migration, and if a migrated module has a problem, you're debugging one module, not the whole system.
6. Risks, and how to de-risk each one
Every one of these has shown up in real migrations. None of them are reasons not to migrate — they're reasons to plan around them.
- Silent loss of business logic. The biggest risk by far. A rule buried in a form's event handler gets missed during the rewrite and nobody notices until a customer complains about a wrong calculation weeks later. Counter it with the business logic extraction step in the assessment phase, plus a business owner who signs off on each migrated module's behavior against real scenarios, not just a code reviewer checking syntax.
- Insufficient test coverage. VB6 apps almost never have automated tests. Migrating "by feel" means you find regressions in production. Before migrating a module, write tests against the existing VB6 behavior where you can, or at minimum document expected outputs for a representative set of inputs, so the .NET version has something concrete to be checked against.
- Unreplaceable COM controls. A third-party ActiveX control from a vendor that no longer exists is a real dead end. Budget time to either find a modern equivalent, build a thin replacement, or, as a last resort, keep that specific piece running via COM interop indefinitely rather than blocking the whole migration on it.
- Database drift during the transition. If both VB6 and .NET modules write to the same database during a phased migration, a schema change made for the .NET side can quietly break the VB6 side. Keep the database change process visible to both teams, and run it through the same review regardless of which language wrote the change.
- No rollback plan. If a newly migrated module fails in production and there's no way back to the VB6 version, a small bug becomes a business outage. The parallel-run step in the phased approach exists specifically so you can flip back to the old path if the new one isn't ready.
The common thread: run new and old side by side wherever you can, and get real test coverage on the behavior you're replacing, not just the code you're replacing it with.
7. What it actually costs and how long it takes
These numbers vary by app, but they give you a realistic starting range instead of a guess.
| App size | Typical scope | Timeline | Budget (managed India team) |
|---|---|---|---|
| Small | Under 20 forms, one database, no COM dependencies | 6–10 weeks | $20,000–$45,000 |
| Mid-size | 50–150 forms, some ActiveX controls, a few integrations | 4–8 months | $60,000–$180,000 |
| Large / ERP-scale | 200+ forms, deep COM interop, decades of business logic | 10–18+ months | $250,000+ |
Hiring US-based .NET contractors at market rates for the same scope typically runs 2 to 4 times higher than the figures above, since a senior US .NET developer alone commonly costs $140,000 to $185,000 a year in base pay. The gap isn't a difference in the work being done — it's the labor market you're hiring in.
One cost driver that's easy to underestimate: replacing third-party controls that have no vendor support left. If your app leans on five or six ActiveX grid, chart, or reporting controls from vendors that folded in the 2010s, budget extra time for finding, licensing, or building replacements — this alone has pushed migrations 20–30% over their original estimate more than once.
8. The skills your migration team needs
A VB6 migration is a strange hiring problem: you need someone who's comfortable in a language most current developers have never touched, paired with someone who's fluent in where you're headed.
- C# and modern .NET. Syntax alone isn't enough — you want someone who understands idiomatic .NET patterns well enough to write code that stays maintainable five years from now, instead of a mechanically converted file that only technically compiles.
- Working VB6 literacy. Someone on the team needs to be able to read VB6 comfortably enough to spot the subtle behavior differences between VB6 and C# — implicit type conversions, error-handling patterns (On Error Resume Next has no direct C# equivalent), and default property behavior that doesn't carry over cleanly.
- Database skills. Most VB6 apps sit on SQL Server or, older ones, an Access/Jet database. You need someone who can read the existing schema, spot logic hiding in stored procedures or triggers, and handle a Jet-to-SQL-Server move if that's part of the scope.
- COM interop experience. Specifically, hands-on experience calling COM components from .NET and exposing .NET assemblies back to COM — this is the technical backbone of every phased migration strategy in section 5.
- UI framework depth in your chosen target. WinForms, WPF, or Blazor, depending on what you picked in section 3 — someone who's actually shipped production UI in that framework, not just followed a tutorial.
9. How to hire the team
For a mid-size migration, the team is usually smaller than people expect: one senior .NET engineer who also reads VB6, one mid-level .NET developer for the mechanical conversion work, and a database specialist part-time for the schema and data-layer questions. A solution architect leads the assessment and the phased plan for anything beyond a small app — someone who's actually done this kind of legacy-to-modern move before and can spot where the COM interop and business logic risks are before they become production incidents.
A few things worth checking before you commit to a team, agency, or individual contractor:
- Ask for a specific example of a VB6 (or comparable legacy) migration they've completed — not "we do modernization," an actual before-and-after story with a rough scope and timeline.
- Confirm they'll run the assessment phase from section 4 before quoting a fixed price. A quote given without a code inventory and COM audit is a guess, not an estimate.
- Check whether they default to a phased approach or a big-bang rewrite. For anything beyond a small app, a team that only offers big-bang hasn't done many of these.
- Make sure the engagement includes a business-logic sign-off step, not just code review — someone on your side who actually understands the business rules needs to validate migrated behavior against the original.
10. Why an India-based team fits this work
This isn't a generic outsourcing pitch — it's a specific fit. A meaningful share of the world's VB6-to-.NET migration work over the past two decades has been done by Indian IT services engineers, simply because so many Fortune 500 companies routed exactly this kind of legacy modernization through their India engineering centers as .NET matured through the 2000s and 2010s. That history means the .NET talent pool here includes people who've done this specific migration before, not just people who know C#.
The cost math is the more immediate reason. A senior .NET engineer through a managed India team runs around $3,200 a month, all-in — salary, compliance, equipment, management, no separate recruitment fee stacked on top. The comparable US senior .NET hire runs $140,000 to $185,000 a year in base pay alone. That's a 60–75% saving on the exact skill set this migration needs, and it holds whether you're staffing one engineer or a five-person team.
On talent depth: India has one of the largest active software developer populations anywhere, somewhere between 4.3 and 5.8 million depending on the source, and it's growing roughly 11% a year — about double the US growth rate. That scale matters specifically for legacy migration work, because it means there's still a real bench of engineers who came up through .NET Framework and older VB before specializing in modern .NET, instead of a market where everyone under 35 has only ever touched React and Node.
On quality: 174 of the Fortune Global 500 run more than 390 engineering centers in India, employing over 950,000 people, and legacy application modernization (moving mainframe, VB6, and older Java systems to current platforms) has been core work for many of those centers for years, not a side project. India also holds the highest concentration of CMMI Level 5 and ISO 27001 certified IT firms of any country in the world. The rate you pay reflects cost of living in India, not a lower bar for the work.
On overlap: IST sits roughly 9.5 to 10.5 hours ahead of US time zones. On a shifted schedule, that gives you a live overlap window with US-East in the morning for standups and questions. Because the team is deep into a migration during your evening and overnight, you often come back the next morning to a completed module ready for review, instead of waiting on it during your own working hours. It's a genuine advantage for a project made up of discrete phases, not a workaround you have to tolerate.
On IP: every engagement should run on a work-for-hire contract with IP-assignment clauses, so the migrated codebase, every C# file and every Terraform or deployment script, belongs to you from the first commit, backed by an NDA and India's Digital Personal Data Protection Act 2023.
11. Frequently asked questions
Is VB6 still supported on Windows 11?
The VB6 IDE has had no Microsoft support since April 2008. The VB6 runtime (msvbvm60.dll) still ships and works on Windows 11 today under a legacy support commitment, but Microsoft has never promised that continues past the current Windows lifecycle, and driver, security, and 64-bit compatibility gaps already break older VB6 apps in the wild. Treat "it still runs" as a fact about today, not a guarantee about your next OS upgrade cycle.
Should I rewrite my VB6 app or use an automated converter?
It depends on the app. Automated converters (like the old VB Upgrade Wizard, or newer commercial tools) work reasonably well for straightforward forms-and-data apps with little COM/ActiveX usage, and they get you running .NET code fast. For anything with heavy COM interop, custom controls, or business logic tangled into form event handlers, a converter produces code that compiles but is barely maintainable. Most teams end up doing a hybrid: convert the mechanical parts, rewrite the core business logic by hand.
How long does a VB6 to .NET migration take?
A small app (under 20 forms, one database, no COM dependencies) can move in 6 to 10 weeks with a small team. A mid-size line-of-business app (50 to 150 forms, some ActiveX controls, a handful of integrations) typically runs 4 to 8 months. Large ERP-scale systems with decades of accumulated business logic have taken well over a year for other companies, and rushing that timeline is how migrations fail in production.
What does a VB6 to .NET migration cost?
For a mid-size application, budget roughly $60,000 to $180,000 all-in if you are hiring a dedicated offshore team, and 2 to 4 times that if you are hiring US-based .NET contractors at US market rates. The exact number depends on form count, how much custom business logic lives in the code versus in stored procedures, and how many third-party or COM controls need replacing.
Do I need to migrate to .NET 8 or is .NET Framework 4.8 good enough?
.NET Framework 4.8 is Microsoft's last release of the Framework line — it still gets security patches, but it gets no new features, and it only runs on Windows. .NET 8 (and the annual releases after it) is where active development happens, and it runs cross-platform. If you are migrating anyway, moving straight to modern .NET avoids a second migration in a few years. The only real reason to stop at .NET Framework 4.8 is a hard dependency on a Windows-only COM component you cannot replace yet.
Can I migrate a VB6 app gradually instead of all at once?
Yes, and for anything beyond a small app, gradual is usually the safer choice. The common pattern is a strangler approach: wrap the legacy VB6 app, migrate one module or one business capability into .NET, route that traffic through the new code, and repeat. It takes longer in calendar time than a big-bang rewrite, but it keeps the business running throughout and gives you rollback points if something breaks.
What happens to my Access or SQL Server database during migration?
In most VB6 migrations, the database survives untouched, or nearly so. The application layer changes, not the data model, unless the database itself has problems worth fixing (no foreign keys, business logic buried in triggers, an old Jet/Access file that needs to move to SQL Server). Plan the database work as its own separate track — don't let a database redesign block the application migration, and don't let the application migration force schema changes you haven't tested.
What is the biggest risk in a VB6 migration?
Undocumented business logic. VB6 apps built over 15 or 20 years accumulate rules that live only in a developer's memory and in scattered event handlers — a discount calculation, a validation exception for one customer, a report format nobody wrote down. The technical part of moving code from VB6 to C# is well understood. The risk is silently losing or misreading a business rule during that move and not catching it until it costs a customer money.
Can VB6 and .NET code run side by side during the transition?
Yes. COM interop lets .NET code call VB6 COM components and (with more friction) lets VB6 call into .NET assemblies exposed as COM. This is exactly what makes the strangler approach possible — you keep the parts you haven't migrated yet running as-is while new .NET modules take over piece by piece, instead of freezing feature development for months.
Why hire a migration team in India instead of locally?
Cost and depth, mainly. A senior .NET engineer in India runs roughly $3,200 a month all-in versus $140,000 to $185,000 a year for the same seniority in the US — a 60 to 75 percent saving. India also has one of the largest active .NET and legacy-VB talent pools left anywhere, because so many GCCs and IT services firms cut their teeth on exactly this kind of migration work for two decades. You are not trading quality for price here; you are hiring engineers who have done this migration before, for less than a single US hire would cost.
Ready to plan your VB6 migration?
Chat with Alex — tell him your app's size and complexity, and he'll help you scope a .NET engineer, a solution architect, or a full migration team. Interview-ready profiles in 48 hours.
7-day risk-free trial. No commitment. No credit card.
Related articles and pages
Hire .NET Backend Developers in India
C# and .NET engineers vetted for exactly this kind of migration work.
HireHire Backend Engineers in India
Database, API, and business logic depth for legacy modernization projects.
HireHire Solution Architects in India
Lead the assessment and phased plan for a migration this size.
EngagementBuild Your Team in India
How the managed hiring model works, end to end.
EngagementDedicated Teams
A full team assigned to your migration, not a single freelancer.
Engagement ModelsStaff Augmentation vs Dedicated Teams
Which model fits a project-based migration versus ongoing maintenance.