Refactor, rearchitect, or rewrite? How to choose for a large existing application

Paul Gordon

July 8, 2022

Every engineering organization has an application it decided not to modernize, and for good reason: the project would take years and might break production. The question of how to modernize it, whether to refactor, rearchitect, or rewrite, was usually academic, because none of the three options was affordable for a system nobody fully understood.

That is the part that changed. AI coding tools can now do the writing. What they cannot do on their own is decide which of the three paths fits a given application, or produce a change to a large existing system that is safe to ship. This post is about the first problem: how to choose. The close is about the second.

Three options that are usually confused with four others

Gartner’s familiar list of modernization options runs to seven. It helps to split them in two.

Migration options move the application without changing its structure. Encapsulate wraps it in APIs. Rehost moves it to new infrastructure as-is. Replatform makes minimal changes so it runs on a new platform (a managed database, a container). All three are legitimate, and all three leave you with the same application you had, running somewhere else.

Modernization options change the architecture. Refactor, rearchitect, and rewrite (replace, buying instead of building, is the fourth and out of scope here). These are the options that change what the application can do and how fast your team can change it.

If the business case says “we need to be on the cloud by Q3,” you are choosing among migration options, and the choice is mostly about cost and risk tolerance. If the business case says “we need to ship features faster,” “we need to get off Windows licensing,” or “we need this application to work with the AI coding tools every other team is using,” you are choosing among modernization options, and the rest of this post applies.

What each option is, in plain terms

Refactor restructures code without changing its external behavior. The Agile Alliance definition still holds: improve the internal structure while preserving what the software does. In a large existing application, refactoring means splitting tangled code into modules with clear boundaries, removing dead code, consolidating duplicated logic, and reducing coupling between parts that should not know about each other. Refactoring is incremental by nature (the strangler fig pattern is the usual shape). Each change can be tested against the old behavior, which is why it is the lowest-risk of the three and the usual starting point.

Rearchitect changes the structure to gain capabilities the current one cannot provide: horizontal scaling, independent deployment of components, a different data model, a different runtime. Moving a monolith to modular services is rearchitecting. So is separating a stored-procedure-heavy database from the application logic that depends on it. Rearchitecting carries more risk than refactoring because behavior changes are expected, not accidental, and it depends on knowing the current architecture accurately before you design the target one.

Rewrite builds a new application from scratch to replace the old one. It is the cleanest option on a whiteboard and the riskiest in practice. Rewrites need a feature freeze on the old system, they lose the business rules that live only in the code, and they take long enough that the requirements move underneath them. The Netscape browser rewrite is still the cautionary tale twenty-five years later for a reason.

Six questions that decide it

Gartner’s evaluation factors are a useful checklist: business fit, business value, agility, cost, complexity, and risk. In practice the decision comes down to six questions about the specific application.

  1. Is this the right application to modernize at all? Check business importance, whether a commercial product could replace it, and how much of the estate’s technical debt lives in it. Modernizing the wrong application is the most expensive of the common modernization pitfalls.
  2. Does the current structure block the business goal, or just slow it down? If features take too long because the code is tangled, refactor. If the application cannot do the thing at all (scale a component independently, run without Windows, expose a domain to another team), rearchitect.
  3. How much of the business logic is documented anywhere other than the code? The less that is written down, the worse a rewrite looks, because a rewrite has to rediscover every rule. Refactoring and rearchitecting preserve the logic by construction.
  4. Can you test that the new behavior matches the old? If you cannot generate tests from how the application behaves today, every option is riskier than it looks, and rewrite is riskiest.
  5. What is the risk-adjusted cost? Divide the project cost by its probability of success. A cheaper option with a low probability of shipping is more expensive than it looks. The concept matters more than any specific number.
  6. What order will you work in? Business logic first, then data, then the user interface. One domain at a time, not the whole application at once. The option you choose has to be one your team can execute in that order.

Most large existing applications end up with a combination: refactor to establish module boundaries, rearchitect the domains where the structure itself is the problem, and rewrite only the pieces where the technology stack has to change (a .NET Framework layer moving to .NET 10, a stored procedure becoming application code; see full-stack Windows modernization).

Why the choice is different in 2026

Until recently the honest answer to “refactor, rearchitect, or rewrite?” for a 5-million-line application was “none of the above, because we cannot afford any of them.” Two things changed.

AI coding tools such as Kiro, Claude Code, AWS Transform, and others can now do the writing. Refactoring a module, rewriting a domain against a specification, or upgrading a framework is work these tools do well when they are given a bounded, well-specified task.

What they struggle with is the size and ambiguity of a large existing system. Past roughly 500,000 lines of code or 1,000 classes, the whole application does not fit in a context window, and static analysis surfaces every dependency with no signal about which ones matter in production. Left to work from the code alone, the tools produce changes that are plausible and wrong.

So the decision has moved. The question is no longer “can we afford to touch this application?” It is “can we give the tools that will touch it a target architecture, a specification for each domain, and tests that prove the new code behaves like the old?” When the answer is yes, refactoring and rearchitecting a large existing application become a series of tested changes rather than a multi-year bet, and the rewrite option shrinks to the components where it belongs.

Where vFunction fits

vFunction is a modernization platform for large existing Java and .NET applications. Using runtime analysis and proprietary data science, it captures how the application actually runs in production and helps your architects define a target architecture before modernization begins. It generates a specification for each domain from the observed runtime flows, with the architectural issues found during analysis factored in, and integration tests from the same runtime data. Kiro, Claude Code, and other AI coding tools receive them through vFunction’s MCP server and downloadable skills, and refactor and rewrite the application one domain at a time under your team’s review. vFunction’s engineers run the process with your team until your team can run it alone.

That is what turns “refactor, rearchitect, or rewrite?” from a budget question into an engineering one.

Keep learning: How vFunction works · Application modernization: the complete guide

Tell us about the application

Paul Gordon

As Senior Director of Marketing at vFunction, Paul oversees the company’s go-to-market strategy. He is a technical marketing executive with over 12 years of experience rooted in B2B SaaS, AI, and cloud infrastructure. Previously, as Director of Product Marketing at Matilda Cloud, Paul drove key partnership initiatives with hyperscalers and service organizations. He also brings extensive experience guiding segment marketing and channel partnerships from his time at Schneider Electric. Paul holds a degree in Electrical Computer Engineering with minors in Business, Mathematics, and Computer Science from the University of Iowa.

Get started with vFunction

Accelerate engineering velocity, boost application scalability, and fuel innovation with architectural modernization. See how.