When a company decides to modernize a legacy system, the first question is which method to use. That choice largely determines the cost, the timeline, and the risk of the whole project. Yet the trade-offs between the methods are rarely laid out side by side.
This post compares the five main options and is honest about where each one fits, including where ours does not.
The five options
| Method | What it is | Timeline | Cost | Risk | Future-readiness |
|---|---|---|---|---|---|
| Rehost | Move the infrastructure, keep the code | Short | Low | Low | Low |
| Replatform | Change the runtime environment, minimal code changes | Short to medium | Low to medium | Low to medium | Low to medium |
| Rewrite | Rebuild from scratch, starting with requirements | Long | High | High | High |
| Replace | Adopt a package or SaaS product | Medium to long | Medium to high | Medium | Medium to high |
| Automated conversion | Parse the code and generate a modern equivalent | Medium | Medium | Low to medium | High |
Rehost: life support, not modernization
Moving from on-premises to cloud, or from old servers to new ones, is useful as an infrastructure refresh. But the code stays exactly as it was, so the real problems remain: the system is still a black box, and the people who understand it are still retiring. Rehosting buys time against an end-of-support deadline. Treat it as that, not as modernization.
Replatform: the environment improves, the debt stays
Replatforming moves the middleware or runtime and touches the code as little as possible. It is a step further than rehosting, but the maintainability of the code itself does not change.
Rewrite: the ideal option on paper, and the one that fails most often
A from-scratch rebuild clears the technical debt and lets you rethink the business process at the same time. It looks like the ideal choice. In practice, rebuilding a core business system has one of the highest failure rates of any large IT project.
The reason is simple. In a system that has been modified for decades, the only accurate specification is the code itself. A rewrite therefore starts with an enormous hidden task: reconstructing the current behavior as requirements. Whatever gets missed surfaces late, during final testing or in production, and the rework compounds from there.
Worth knowing: this risk can be reduced even if you have decided to rewrite. Parsing the existing code into a structured model — the same analysis that powers automated conversion — produces an inventory of the system’s actual behavior: every screen, rule, calculation, and dependency, along with the dead code you can drop. That extracted as-is specification becomes the checklist the rewrite is built and tested against, so “did we cover everything?” stops being a guess. You still rebuild from scratch; you just stop rebuilding from memory.
Replace: the strongest option when your process fits the standard
For standardized functions like accounting or HR, a package or SaaS product is usually the first thing to consider. The trap is applying it to the processes that make your business distinctive. Forcing those into a package produces a mountain of add-on customization, and you end up rebuilding your legacy system on top of someone else’s product. The dividing line is knowing which processes can move to a standard and which are worth keeping as custom software.
Automated conversion: keep the asset, replace the technology
Automated conversion parses the existing code into a structured model, then generates a modern equivalent from the model: TypeScript and React on the front end, with current frameworks underneath. This is how our process works.
The main advantage is that the business logic embedded in the code carries over as it is. The largest risk in a rewrite, reconstructing the specification, simply does not arise, because the specification is extracted from the code rather than rewritten from memory. Tests are generated alongside the conversion, so old and new behavior can be compared mechanically as the work proceeds.
In our projects, conversions from stacks like PowerBuilder, VB6, and Nexaweb run at 90%+ automation. The case studies show what that looks like on real systems.
Where automated conversion fits, and where it does not
To be fair, automated conversion is not the answer to everything.
It fits when:
- The business logic in the current system is an asset you want to keep
- The documentation no longer matches reality, so the cost of reconstructing the spec is unknowable
- The business cannot stop, and you need to migrate in stages
- The source system is built on a structured platform: client/server tools, 4GL environments, RIA platforms, and similar
It does not fit when:
- You want to fundamentally redesign the business process itself (pair a rewrite or a replacement with the process change — though even then, parsing the current code to capture the as-is functionality gives the rewrite a complete baseline, as noted above)
- Most of the current functionality is no longer needed (discarding and rebuilding a small core is faster)
- The function is standard and a package fits (replacement is the rational choice)
In practice, the answer is usually a mix
Real projects rarely modernize everything with a single method. The practical approach is to inventory the system first, then apply different methods to different areas:
- Distinctive core processes: automated conversion, keeping the logic and modernizing the technology
- Standardizable supporting processes: replace with a package or SaaS
- Unused functionality: leave it out of the migration entirely (analysis typically finds a significant amount of dead code)
How well you can make these cuts depends on how well you understand the current system. That is what the analysis phase of our process quantifies: size, complexity, dependencies, and dead code.
Summary
There is no universally correct method. But for a system whose only accurate specification is its own code, going straight to a rewrite is the riskiest path available. Include automated conversion in the comparison, and combine methods by area rather than forcing one method onto everything.
If you want to see what conversion produces on your own system, request a POC. We run the process on a representative slice of your code and you review the output before committing to the full modernization.