Your legacy codebase isn’t a nightmare because of the code

Harry Hope
Inside Business Insider
6 min readFeb 23, 2021

At least not the code you’re probably thinking of.

Illustration by Gabrien Symons

Does this situation sound familiar to you? It’s your first day as a software engineer at a new job. Your manager is walking you through the codebases you’re going to be responsible for maintaining:

“Ah, and here’s our bloated, monolithic, legacy codebase that’s been around way longer than I’ve been at the company,” she says. “No one really understands how it all works and the code is a complete mess. No one wants to touch this codebase with a ten foot pole.”

If you’ve worked a few jobs as a programmer at any reasonably sized company you’ve probably heard something along these lines before. Maybe followed by something like: “But don’t worry! We’re working towards breaking down our monolith into a cluster of microservices. That work should be done in another year or two!”

Cringe

I often wonder why this happens. How does a codebase go from being perfectly good and maintainable to a monstrosity so universally loathed by developers that they don’t even want to go near it?

Sometimes I ask developers what they think makes their company’s legacy monolithic monstrosity (LMM for short?) so terrible. More often than not, I get pointed to some quality of the code:

“Well it started in the MVC pattern but now it’s just a hodgepodge of different patterns. There’s no standards whatsoever!”

“Obviously because we’re still on Angular 1.x with no hope of ever migrating. Aren’t they up to like…10.0 by now?”

Here’s my favorite: “I mean it still uses [gasp] jquery! It’s just a bunch of spaghetti code! If only we could use React instead!”

Don’t fix your code. Fix the experience of writing code and over time problems and inconsistencies will fix themselves.

Comments like these aren’t totally off-the-mark. I mean, who wants to deal with jquery spaghetti code? More often than not, I find that developers lose sight of the fundamental problem. One that stares them in the face every day but that maybe, they don’t quite recognize.

For starters, try getting this legacy monstrosity running on your laptop. Not easy is it? “Yeah it typically takes devs a couple days to get our monolith running locally,” you might hear your manager say. Maybe you need a whole host of docker containers running on your machine, or even need to manually install a bunch of related dependencies like databases. Usually these set-ups aren’t documented that well. Maybe as you try and follow along with the outdated readme you encounter a random error. Maybe you’ve tried Googling for the answer or asking other developers on your team but the right answer never quite shows up. After a day or two of troubleshooting you finally get it right by deleting everything and starting over. Miraculously, it works this time.

Great, you think, that was a lot of time and effort but at least now I can start being productive and getting work done! Except soon you find that may not be the case. This app is slow. Maybe it takes an entire minute to compile and run each code change. Maybe reloading the web page that a local server generates takes forever. “We cache aggressively on production so it runs quickly there and generally isn’t a problem,” a fellow developer might say. But it is a problem for you because you can’t make changes, add logging statements or drop in breakpoints without waiting and waiting and waiting. Sometimes you’ll wait for a change to appear and nothing happens at all. Maybe you start to lose focus as your code recompiles or your server reloads for the tenth time. Your mind wanders off. Maybe you start thinking about that next cup of coffee or tea and decide to take a break. Somehow the entire day flashes by and you find yourself leaving work having made virtually no progress feeling more confused and uncertain than you were when you started that morning.

This kind of scenario happens all the time at companies big and small, and in codebases new and old. It’s especially common with really old codebases. As they continue to grow, code drift and code atrophy naturally happen. But what is really atrophying? It’s not the code itself, it’s the experience of writing code. It’s the difficulty in doing the little things that every developer needs to do daily, over and over again: Check out new code, make changes, debug, test, push code to a staging server, run tests. If any of these steps aren’t easy and seamless then it’s going to impact how effectively you can change and improve a codebase. Get enough of these things wrong and you’ll begin to see corners getting cut. Developers begin being cautious and changing as little as possible. They add to that spaghetti code instead of refactoring it because, “I really don’t want to spend another day on this and you know those tests take 20 minutes to run and then flake out anyway.” The overhead of development becomes too much to handle, so development grinds to a halt.

A classic excuse https://xkcd.com/303/

It’s about the experience

Don’t fix your code. Fix the experience of writing code and over time problems and inconsistencies will fix themselves.

By fixing the developer experience you open up your codebase to more contributions from developers. You create an environment that invites change and experimentation instead of impeding it. When there’s low cognitive overhead to making any given change it lets you focus entirely on the problem at hand without distractions instead of getting wrapped up in irrelevant complexities.

Before I begin working in any new codebase, here are some questions I like to ask to help me gauge how effectively I might be able to make changes to it:

1. How long does it take me from cloning the repository to getting a fully working version of the application locally? Does it take a lot of different steps or commands? Is it generally a smooth process or very error prone?

2. How long does it take to get from changing a line of code to seeing the results of that change? Milliseconds? Seconds? Minutes? Does recompilation or reloading happen automatically or do you have to run a command? If so, is it one command or multiple commands?

3. How difficult is it to get any change I make into production? Do we have a robust CI/CD pipeline with lots of automation or is it a more manual process? Do I need to go through lengthy reviews or approvals before code can be deployed? Is actually deploying the code to a production environment fast or does it take minutes or even hours?

Deficiencies in any one of these areas aren’t necessarily fatal, but enough problems over a long enough period of time will impact work and you and your team may start to see productivity decline. Development will become challenging and velocity will slow down.

It also pays to re-evaluate your answers to these questions at certain intervals. Sometimes brand new codebases start out as great developer experiences but overtime grow sluggish due to normal development. Your app might have compiled immediately 6 months ago but now thanks to some additional build steps and a lot more code it’s started to slow down. Or maybe your webpack server used to hot reload your javascript instantly but now after some new plugins it’s taking a full 10 seconds just to display changes in your browser.

As for your legacy monolith monstrosity, try having your team focus on the development experience. You might be surprised how salvageable even the oldest and most incomprehensible codebase is if it just didn’t take so darn long to see your changes show up. And if you do decide you want to re-platform or redesign, use developer experience as a framework for your decision making.

If your new app/service/micro-service is an order of magnitude faster to download, develop, and deploy then you can expect good results over time. However, if your new application is as slow or slower to develop with, it’s not likely to be successful long-term and might not ever even launch in the first place!

Maybe most of what I’ve just written seems like common sense to you, but as the old adage goes, “sometimes common sense isn’t so common.” So the next time you open up your laptop and begin writing code in that legacy codebase you just can’t stand, remember to think about the developer experience — It just might make all the difference.

Looking for a new job opportunity? Become a part of our team! We are always looking for new Insiders.

--

--