top of page

Rewriting vs. Refactoring: What’s the Best Approach for Saving Your Software Project?

Ervin Balázs

Introduction

At a certain point in the lifecycle of most software projects, developers face a critical decision: what to do with the legacy code that has accumulated over time. This question often arises due to a variety of factors, ranging from business needs to technological constraints.

On the business side, slow release cycles, difficulty finding developers familiar with older technologies, or technical bottlenecks might be signaling that something needs to change. On the technical side, teams might realize that the buildup of technical debt—the inevitable consequence of quick fixes or outdated code—could threaten long-term stability and maintainibility.

The two common solutions are to either refactor the existing codebase or opt for a complete rewrite. But which is the best choice? The debate has been ongoing since Joel Spolsky’s famous blog post Things You Should Never Do, where he strongly advised against rewriting from scratch, using Netscape’s ill-fated rewrite as a cautionary example.


What Is Refactoring? What Is Rewriting?


Refactoring

Refactoring is an incremental process where you improve the quality and maintainability of the code without changing its fundamental structure. It’s like renovating an old building: you might modernize parts of it, but the foundation remains intact. Refactoring usually involves working within the existing tech stack—perhaps updating it to newer versions—but not fundamentally overhauling the entire system.


Rewriting

Rewriting, on the other hand, means starting fresh, developing the software (or different modules) from scratch, and often introducing new technologies and architectures. It’s akin to tearing down an old building and constructing a new one, sometimes changing everything from the materials used to the layout of the rooms.


When to Refactor, and When to Rewrite?


When Should You Consider Rewriting?

When new developers join a project they’ve never worked on before, their instinct might be to advocate for a complete rewrite. After all, starting from scratch seems easier than trying to figure out an outdated and perhaps poorly documented codebase. They get a clean slate, a blank repository, and can build without worrying about old logic or hacks that are hard to decipher.

However, the truth is that rewriting is rarely as straightforward as it appears. Rewrites often take longer than anticipated, introduce new bugs, and can cause user churn if key features are overlooked or re-implemented poorly.


That said, there are times when a rewrite makes sense:


  1. Business logic has evolved significantly. If the underlying business rules have changed so much that the current software cannot accommodate them without substantial re-engineering, a rewrite may be the best option.

  2. Outdated technology. If your project is so far behind current technology standards that it lacks an upgrade path to the latest versions, or if you’re using technologies that are no longer supported or maintained, rewriting with modern tools might be necessary.

  3. Complex, cascading changes. If even simple modifications require massive changes across the entire codebase, it may indicate that the current architecture is no longer fit for purpose.

  4. Technological limitations. The original technology choices might be limiting the addition of new, essential features or making development painfully slow and inefficient.

  5. Recruitment challenges. If the technology stack is so outdated that it’s hard to find qualified developers, it might be more cost-effective in the long run to rewrite in a more popular, modern language or framework.


When Should You Choose Refactoring?


Ideally, refactoring is a continuous process. As your codebase evolves, refactoring helps keep it clean and maintainable. This is best exemplified by Uncle Bob’s Boy Scout Rule in his well known book Clean Code, which states: Leave the code a little cleaner than you found it. This rule suggests that whenever a developer touches any part of the code, they should make small improvements rather than letting technical debt pile up.

In practice, though, this approach is often overlooked, and refactoring only becomes a priority once technical debt has already accumulated to unmanageable levels.

Here’s why refactoring is often the better option:

  1. Incremental process. Refactoring can be done piece by piece, allowing you to maintain the system’s functionality while improving its structure, adding new features, etc. You can keep shipping features and updates without having to hit pause on development.

  2. Predictability. Refactoring typically has a more predictable effort-to-outcome ratio. Because you’re working within the existing architecture, the scope of changes is usually easier to estimate. Upgrading to newer versions of technologies often has clear, well-defined steps.

  3. Stability. Refactoring enables you to maintain a lower bug count by continuously applying improvements. When coupled with test-driven development (TDD) practices, refactoring can ensure your system remains robust and healthy.

  4. Gradual releases. You can refactor and release improvements incrementally, reducing the risk of introducing new bugs and allowing for faster deployment of updates.


Conclusion

Before making any decisions about rewriting or refactoring, it’s important to approach the problem thoughtfully. Don’t automatically trust a new team’s instinct to rewrite your codebase unless they provide a strong justification based on business goals and technical needs. Rewrites often seem appealing but can lead to significant delays and unforeseen complications.

Refactoring is a safer, more controlled approach, but it requires continuous effort to be effective. Whichever option you choose, always keep your business strategy in mind and plan accordingly. And when in doubt, consult with an expert who can offer a balanced perspective on the best way to move forward.

Commenti


bottom of page