TechWorkRamblings

by Mike Kalvas

Rewrites Are (Almost) Never the Answer

A Difference Between Desire and Reality

Rewrites are tricky to get right. Despite how often we're drawn to them, they're almost never the right solution.

#blog #work

You Can't Always Get What You Want

As a developer, my first reaction when getting into a legacy codebase is almost always to bulldoze and rewrite it. Unfortunately, rewriting code is commonly a huge mistake for software companies.

If you've been around long enough, you've probably read the classic article by Joel Spolsky, a founder and ex-CEO of StackOverflow where he names rewrites the "single worst strategic mistake that any software company can make." In this article he walks through a dot-com era rewrite by Netscape that was such a bad idea, it can track directly to the downfall of the company.

As developers, want to do rewrites because we get our excitement from building things that we can call our own — grand, shiny towers of our Legos that we can point to and say, "I did that." But according to Spolsky, there's more to it.

There's a subtle reason that programmers always want to throw away the code and start over. The reason is that they think the old code is a mess. And here is the interesting observation: they are probably wrong. The reason that they think the old code is a mess is because of a cardinal, fundamental law of programming:

It's harder to read code than to write it.

This is such a common opinion among developers, there are web comics about it.

Other people's code. https://abstrusegoose.com/432

But why is our desire to rewrite instead of investing time reading and learning the code a bad thing? Maybe this asymmetric relationship with new and existing code is for the best. Maybe it pushes people toward updating code regularly. Maybe it removes cruft and re-invigorates a new generation of developers with a sense of ownership.

The critical factor is that existing code already works and the code that's going to be written has to be made to work.

Years of institutional knowledge and market research have gone into the existing code. Hard won battles were fought between late-night developers, devious bugs, and edge cases. The code that you look at and don't understand was put there for a reason. If you don't understand it, there's a high likelihood that you haven't thought of the bug that it's fixing.

A rewrite throws all of that away in favor of spending money writing code that already exists because we weren't interested in spending the time and effort to read and learn the code.

That said, there is such a thing as messy code. It's important not to let the messy code get the best of us though. We must remember that messy code can be fixed without doing a complete rewrite. If the code is architected poorly, we can spend deliberate, consistent effort slowly refactoring to a good architecture. If it's inefficient, we typically only need to make small fixes in hot paths for big improvements. If it's just ugly stylistically, use a linter or find and replace.

One last thing I want to mention is that we have no well-founded reason to think that we could do a better job than everyone else did. We'll probably make the same mistakes our predecessors went through years ago. We don't have the experience of getting the code to the place it's at now. We can't be sure we have any special information or experience that would make a substantive difference in building this thing from scratch. So how can we justify throwing away what was already built and all its accumulated value, just because we're not happy with how it feels to us?

Obviously, we can't.

Are Rewrites Ever the Answer?

Maybe. I think it's possible to advocate for a rewrite in good faith in certain situations.

A personal experience comes to mind from a startup I worked at. We pivoted into a different product space after one of the smaller things we started doing took off much faster than what we originally set out to do. We made a decision to rewrite some (but not all) of our codebase that was being tortured and contorted into doing something in support of the new product that it was never designed to do for the old one.

We were able to make the scope of the rewrite small and well-defined, and set a very short turnaround that didn't impact our ability to keep moving forward in our new market space. Our salespeople never even had to mention that something like this was going on. If you were on the outside looking in, you never would have known we were doing a rewrite. There wasn't even a blip.

Beyond that, the fact that we did a rewrite was a leg up on starting from scratch without a product at all. We weren't saying, "this code is hopeless, let's throw it away and start from scratch". We were saying, "let's keep as much good code as possible." In that way, our rewrite amounted to more of an aggressive refactor that included huge amounts of cutting away and only small amounts of new code. Wherever possible, we kept existing code even if it meant leaving some dead code from the old system for a while.

It worked out really well in the end, so it must have been an OK choice. Whether it was the absolute best choice, I guess we'll never know.


So the next time you feel that urge and think about doing a rewrite, ask yourself if you're giving in to your feelings on the code, or if you really think it's for the best. Then ask yourself again.