In web development it’s a common trope that working with legacy code is considered boring, painful, or even beneath us. Only the shiniest new framework or tech stack will do! The truth, however, is that legacy code is impossible to avoid. But don’t worry, that’s actually a good thing.
React has been all the rage for about 7 years, but it's in use on only 2% of all websites. The story’s the same for Vue and others. For all their hype, the opportunity to work somewhere that’s using React or Vue in the wild is incredibly niche and privileged!
WordPress, on the other hand, serves up 42% of the web. jQuery is an outcast nowadays, but is still found on a staggering 78% of all websites. Or maybe you’ve heard of COBOL? About 80% of the code running the world—that’s payroll systems, ATMs, traffic lights, and so on—is written in COBOL. That’s over 220 billion lines of COBOL, and nobody ever talks about it.
Hell, if one wanted to make truly serious money it’d be far better to be a COBOL programmer yanked out of retirement. React seems downright quaint by comparison.
Given numbers like these, it’s quite impossible to shape our careers to avoid legacy code.
Any given company might be splitting their aging monolith into microservices, stitching a bunch of microservices back together again, migrating tech stacks or CMS platforms, acquiring smaller companies and their code, relying heavily on some random internal tool that a developer hacked up as a favor to a coworker, and so on.
Even the youngest of tech startups will have a problem with legacy code—they just won’t realize it right away. The greenest of greenfield projects will quickly wither.
So, legacy code is everywhere and runs for years (if not decades) making trillions of dollars a year and delivering value to users. The fact that it does so, and without fanfare, should give us pause. If legacy code is so successful, why do we have such contempt for it?
Dylan Beattie has the perfect definition for legacy code to help us answer this: “Legacy code is code that’s too scary to update and too profitable to delete.”
He also makes the observation that writing new code is more exciting than reading old code. And Joel Spolsky expands on that idea when he claims, “It’s harder to read code than to write it.” He goes on:
Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We’re not excited by incremental renovation: tinkering, improving, planting flower beds.
That’s quite the combination, isn’t it? We’re expected to poke at code that’s “too scary to update” and might fall over if we look at it the wrong way. But... We didn’t write this code... Can’t we work on this killer feature instead? Can we delete this code and start over? This isn’t the luxury and glamor of web development that we were promised!
Let’s be frank—everyone in our line of work can write net new code. That’s the bare minimum expected of us, in this humble author’s opinion. It’s a far more valuable and marketable skill to read, interpret, and understand code. This is the challenge that legacy code puts to us.
And, as is often the case when something is scary, this says more about ourselves than it does about the code. We need to face this head on, stop projecting our foibles onto inanimate codebases, and genuinely improve ourselves and the industry.
Legacy code really is an opportunity and a proving ground for us to perfect many skills and talents. To list just a handful:
- Useful and efficient troubleshooting techniques.
- A heightened sense for patterns or antipatterns.
- New languages or tech stacks that they don’t teach in school.
- Strategies for pragmatic, effective unit testing.
- Battle-hardened architectural decisions and strategies.
- Smarter or more robust bug fixing skills.
That’s not to say any of the above comes easily. We just might have to break the code to understand it—deliberately or otherwise. And likely more than once. And sometimes on production.
And yet, we can probably trust legacy code more than we’d guess! Joel Spolsky again:
The idea that the new code is better than old is patently absurd. Old code has been used. It has been tested. Lots of bugs have been found, and they’ve been fixed. There’s nothing wrong with it.
It is patently absurd, isn’t it? There’s a hubris that’s plainly on display and driving our contempt for legacy code. Even worse, it could be silently influencing the technical strategy for many organizations. Spolsky one last time:
[W]hen you start from scratch there is absolutely no reason to believe that you are going to do a better job than you did the first time. First of all, you probably don’t even have the same programming team that worked on version one, so you don’t actually have “more experience”. You’re just going to make most of the old mistakes again, and introduce some new problems that weren’t in the original version.
Which brings us to one of the most important skills that legacy code can teach us: empathy.
We must remember that almost every codebase we might encounter was without a doubt built with the best of intentions. Decisions were made at a given point in time according to the constraints, assumptions, and best information available. But it never feels like that many years later, does it? While very easy to overlook, understanding these circumstances can help us better interpret the code we're looking at.
And there's a corollary here that might be worrisome to any of us who've tried to tailor our careers to avoid any encounters with legacy code.
There are rockstar developers creating legacy code right this very moment. It doesn't matter if that code is lovingly crafted using the latest tech stack and best practices—in a few years a group of total strangers will beg their manager to print out the entire codebase and set it on fire.
Right now, somebody somewhere is cursing a line of code that one of us has written. So, whether we're inheriting it or producing it, we can't escape legacy code.
Much is done in the name of innovation. We trip over ourselves chasing the shiny and new on a never-ending conveyer belt of frameworks and tooling. And then we snipe at each other on Twitter to justify the energy we've spent staying up to date, or we feel guilty for failing to keep up.
Companies undertake massive overhauls of their codebases, also for innovation's sake. They may fall short of their ambitions or ultimately succeed—only to do it all again years later.
So do we embrace legacy code with open arms and avoid modernizing? Or vice versa? No, of course not. But at this point it should be obvious that when it comes to code—old or new—there are many influences at play and most of them aren't technical.
Let's recognize that legacy code and unbridled innovation are at opposite ends of a spectrum, and that we can learn, improve, and extract value from the gap in between. Legacy code will always be with us and a healthy attitude about it favors developers, companies, and the entire field of web development.
Image is courtesy of Matt Hogg.