As a freelancer you will come across many times where you make a decision on starting over vs refactoring on a legacy project. Through the years I have come across this issue more times than I can count.
The Legacy Scenario
Typically the situation sounds something like this. I’ll get hired by a client who has a legacy application. The application is usually a few years old and has been managed by a number of developers. I’ve discovered that usually the code project started out small, and it grew from there.
Somewhere along the way the application lost its way. Instead of using a scalable application design approach, the previous developer patched new features on and the codebase devolved into a convoluted mess. Eventually every new feature causes another component to break and the client gets so frustrated he decides to hire me.
Does this scenario sound familiar to you at all? As a freelancer I’ve been on both sides of the legacy code spectrum. When I was a new developer I built new projects that got out of hand and I lost the clients. And as I matured as a developer I started getting hired to take over legacy projects.
I can tell you from experience that neither side of this scenario are fun. Especially when the client brings up the dreaded topic of starting over vs refactoring.
Starting Over vs Refactoring
When I was a young and naive freelancer I dreaded the idea of re-factoring a legacy application. The second that the client brought up the possibility of starting over from scratch I jumped on it! However the more projects I work on, the more my mindset has changed.
Over the years I’ve put together a system to help me decide between starting over vs refactoring a project. And that’s what I’m going to walk through here. The steps I follow are:
- Removing the fear factor
- Analyzing the 80/20 principle
- Building an automated bug list
- Becoming the client
One of the reasons why inexperienced freelancers tend to opt for starting a project over is because of fear. And fear is rarely a good reason to make any decision (unless you’re running away from a wild animal or something like that).
So before I make a decision, the first task I perform is taking fear out of the equation. I’ll ask myself:
“If you weren’t afraid of the unknown issues with this codebase, what would your decision be?”
Once fear has been removed I can look at the project with an unbiased viewpoint.
The 80/20 Principle
The 80/20 principle has a number of practical ramifications. You may have heard it being used to say that 20% of the people make 80% of the wealth. Or that 20% of a customer base generate 80% of a company’s revenue.
However I’ve also seen that the 80/20 principle can work well for deciding between starting over vs refactoring.
Too many times I’ve seen a freelancer start a project from scratch when the legacy application already contained 80% of the functionality needed from the client. This means that the developer only needed to take care of the remaining 20%.
If you look at the numbers the answer becomes readily apparent. Would you rather perform 100% of the work (which is what would be needed when starting from scratch), or only 20%?
So at this step I take a step back and I analyze what features the client is asking me to build. If the legacy application is functional and simply has a messy codebase, it’s rarely the smart move to start over from scratch.
Typically in this case I’ll add the new feature and then start refactoring the application one module at a time.
Automated Bug List
Moving down my list I’ll next use automated tools for analyzing the application. Pretty much every programming language and framework has a wide range of analysis tools. I’ll utilize these tools to generate a set of issues for the legacy application.
I like this step because it accomplishes two key goals:
- It gives me a practical strategy for what needs to be fixed in the application.
- Since it’s automated, these types of tools are unbiased. Your personal judgments on the previous developer’s coding style are taking out of the equation. And the focus is centered solely around the project itself.
While each project is unique, the tests I run usually focus on giving me a report on:
- Potential security issues
- Best practices
- Code that is not being utilized (this is vital!)
Becoming the Client
Lastly I try my best to remove my personal feelings from the decision. Instead I focus on taking the perspective of the client. I’ll ask myself:
“If I was a fully informed client, would I really want to pay for a developer to start the project over from scratch?”
Using some fuzzy math I’d estimate that around 9/10 times my answer to this question is that an informed client would request a refactor over starting over.
Starting a project over is expensive, and there’s no guarantee that the new codebase is going to be perfect. In fact I can pretty much guarantee that there will be issues with a brand new application. I’ve seen multiple times where a legacy application was replaced by a new piece of software that had the same number of bugs.
When Should You Start Over?
So far this guide has heavily favored refactoring an application. However there are times when starting over from scratch is a better approach. Some of the rationales that make starting over a wise decision for the client are:
- A complete change in architecture. I have had clients who requested that I migrate an application from being a monolith (a large single application) to becoming microservice based (a number of applications that all only perform a single feature). In cases like this it wouldn’t make any sense to try to keep the legacy application since the core application structure would have to change.
- Moving to a different language/framework. Through the years I’ve had a number of clients who had old ASP .NET and PHP applications approach me to rebuild their systems in Ruby. When it comes to changes languages or web frameworks it wouldn’t be possible to retain the legacy application.
Notice how both of these key reasons had nothing to do with bugs or messy code? The only time I’d recommend for a client to start over from scratch is if it’s literally impossible to retain the legacy application.
In summary, the key to remember is to go through the system of checks whenever you’re asked to decide between starting over vs refactoring. The more experienced you get as a developer the more you’ll realize that it’s incredibly rare that a functioning legacy application cannot be saved.