I'm a big fan of Joel Spolsky's earlier blog posts, but to be honest, I don't think this piece has aged well. If anything, I'm more of the opinion now that you should almost <i>always</i> plan to do a rewrite, eventually. Lots of big companies successfully rewrite stuff all the time. Google is fairly well known for having rewritten large, critical pieces of their codebase over the years.<p>If anything, what should be warned against is <i>big bangs</i>. Netscape's problem isn't that they did a rewrite (which eventually became Firefox, mind you) it's that they essentially abandoned their old code too early, and similarly, they also announced the rewrite too soon.<p>If you're going to do a rewrite, do it quietly, and don't announce it until it's close to ready, and even then you can roll out slowly. For example, the infamous Digg v4 debacle is another example, but the problem isn't that they did a rewrite, it's that they did a rewrite to produce a product nobody wanted, and they burned any possibility of going back after they released it.
I once rewrote a monstrous app that was in development for 5 years (!), in just one month. In terms of LOC it was 20 times smaller than the old codebase. Had the same functionality and then some more. It had zero bugs in the first release, compared to myriad of bugs in the previous one (mostly multithreading related - yes it's hard).<p>All I did was, I dumped Microsoft's COM/DCOM and replaced it with REST; also replaced C++ and VB with C#. Totally made sense to rewrite from scratch and it was a big win with absolutely no downsides. Like, <i>no downsides whatsoever</i> because otheriwse the same month I would have spent fixing maybe 4 or 5 multithreading bugs in the old codebase.<p>Anyway, never say "never do X" because you are most likely wrong.
I think saying "you should never rewrite code from scratch" is a bit too dogmatic. There's a cost and risk tradeoff. I think people underestimate the cost of a rewrite (Due to ego or NIH or yak shaving), but I don't think it's never the answer.<p>Sometimes the language is so old it's cripplingly expensive to hire programmers in. Sometimes the code is deeply tied to a hardware architecture that is extinct. Sometimes the legacy code actually is that bad.<p>For reference, I've done total rewrites on two different small-ish software projects - in both cases because the original author had made design choices that made the whole thing unsustainable in the long run (no blame implied, it's more about shifting goals).<p>For reference, Twitter has done a total rewrite of their large codebase, and lived to tell the tale.
« It’s important to remember that when 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 »<p>With the benefit of twenty years of hindsight, I think the programmers who performed the rewrite in question did a better job than the original Netscape implementation.<p>Come to think of it, I'm typing this message on the direct descendent of that rewrite, while the competitor to whom they gave « a gift of two or three years » has been forced to abandon their codebase in favour of a third-party one.
Joel classic, and it always reminds me of times I've seen this happen again and again years after it was written. I don't think I've ever seen a full rewrite bring all of its heralded benefits. I'm sure there are some people who have. There always end up being things the old system did better, and sometimes you wind up with the old and new systems running in parallel because end users need to switch back and forth until v2 is finally mature (it seemingly never finally matures).<p>That said, I'm in favor of a rewrite when the use cases for the platform have diverged so significantly that you essentially have to bend it in half to make it do the thing that users want it to today. That is, as some point the core use cases have changed, perhaps via a pivot, and you need to build a product that is essentially new as compared to the old.<p>Regardless, the cases where I've seen a rewrite take place are when the engineers are young, talented, and enthusiastic about new tech and the engineering manager doesn't want to piss them off so they let the devs play (most of them will be off to other jobs in 2-3 years leaving behind a system that is debatable as ugly and busted as the old).
Always important to mention the alternative, a "Strangler Fig Application", also known as the strangler pattern.<p><a href="https://martinfowler.com/bliki/StranglerFigApplication.html" rel="nofollow">https://martinfowler.com/bliki/StranglerFigApplication.html</a>
There's a Domain-Driven Design pattern that encapsulates this entire problem. First, never even think about rewriting an entire system. You will likely fail. Not because you're not smart and capable, but because the business won't be patient enough to allow you to do it properly. And they'd be right not to be patient. They have things to sell and customers to support...today.<p>That's why Eric Evans came up with the Autonomous Bubble pattern. You rebuild features one at a time and connect them to the old code through anti-corruption layers and translation layers. Over time, the older code will be set aside. In a year or two, the plug will have naturally been pulled on all of the older code.<p>So there's some truth to Spolsky's 2000 blog post. But it's not smart to maintain older code forever either. You have to be careful, thorough, and use the right tools.
Max's answer to the interview question "What is the most terrible code that you ever encountered, and what was your approach to refactoring it?" is relevant here.<p>In his book "Code Simplicity", Max has a checklist (summarized in point 4 of <a href="https://techbeacon.com/app-dev-testing/rewrites-vs-refactoring-17-essential-reads-developers" rel="nofollow">https://techbeacon.com/app-dev-testing/rewrites-vs-refactori...</a>) -- and that's the checklist referred to in the InfoQ interview.
I completely agree! Throwing away your code and starting over is failing to atone for the sins of the past, and I feel like it prevents you from learning or growing as a programmer. That's why I don't think I'll ever rewrite something from scratch again.<p>To me, this was nowhere more obvious than from my old co-worker who was constantly trying to rewrite the internal site we worked on. First it was angular and coffeescript, but that was apparently unmaintainable after 3 months (!!!). So they rewrote it and then I joined, and it apparently made it to 6 months. Then we tried to rewrite it in TypeScript and React which blew 10 man weeks away before we abandoned it. And then he tried to do TypeScript and Angular again but it never launched.<p>Meanwhile, after the React debacle, I learned my lesson and focused on rewriting and rearchitecting the old code to follow more modern Angular practices (1.5 components and such), and suddenly the code didn't seem so unworkable anymore! Quality improved and features were added that made it a very popular internal site, still in use 3 years after I left that team.<p>So I agree, I think you should always try to improve what you have instead of starting over. (If only our UX designers would go for incremental improvements too...)
Never say never, but still a lot of truth to this. I generally think refactoring is the better way to go unless you are backed into an architectural corner. Say, for instance the app was built in power builder and needs to support 64 bit OS. That’s a rewrite in a new language. Say the app was a MacOS 9 and OSX is coming. Rewrite. Otherwise it’s probably better to refactor old code than to chase green fields.
I've heard such thoughts expressed as "Evolution, not Revolution". You evolve (refactor) your old app into the new one, rewriting parts of it at a time.<p>Several comments have already expressed that they've rewritten projects successfully. I've also evolved several projects successfully too. One of the benefits of the evolution approach is that when old bugs resurface, they're less likely to show up all at once since you only changed part of the application. Also it should be easy to compare the code with the bug to the previous code without the bug because it mostly similar.<p>There are times when an application is beyond repair and a rewrite is necessary, but I see those times as the exception rather than the norm.
Currently on a project where I find myself thinking a lot about this post. I think a lot of the comments here are missing some of the finer points of this argument. "Rewriting" is not per se the problem, "rewriting from scratch" where a project is effectively put on hold until the rewrite gets done, is the real quagmire. There are legitimate ways of doing a rewrite that don't require boiling the ocean and prevent you from shipping. And I'm sure there are exceptions as well, but as a general piece of advice about software engineering I've found this to have a better shelf life than many other nuggets of advice.
From the three dozen or so previous submissions, the actual discussions seem to be:<p>2013 <a href="https://news.ycombinator.com/item?id=6327021" rel="nofollow">https://news.ycombinator.com/item?id=6327021</a><p>2012 <a href="https://news.ycombinator.com/item?id=3624830" rel="nofollow">https://news.ycombinator.com/item?id=3624830</a><p>2012 (a bit) <a href="https://news.ycombinator.com/item?id=3449953" rel="nofollow">https://news.ycombinator.com/item?id=3449953</a><p>2009 <a href="https://news.ycombinator.com/item?id=608431" rel="nofollow">https://news.ycombinator.com/item?id=608431</a>
Refactoring code is a continuum, from "let's do nothing" (0%) to let's rewrite the whole damn thing" (100%). There's a whole spectrum in between.<p>While I'm a "never say never" kind of guy, I do think many well-intentioned engineers make a leap to the 100% solution too easily. There are lots of other tools in the toolbox that can de-risk the process, like becoming more service oriented, implementing facade patterns, etc., which all in some way or another work towards a "rewrite" usually without ever rewriting everything.<p>Sometimes you get the benefits of the 100% solution with 25% of the work, and without most of the risk. "Yeah, that part of the codebase is old and crufty, but we never have to touch it because it Just Works and there's no point in rewriting it."
I have successfully rewritten a major codebase. It took about two years to implement. It helped that it involved moving from a mostly proprietary stack to a mostly FOSS stack, which allowed us to leverage the community and spent more time on business features rather than plumbing.
It is hard to defend position "never rewrite" (because sometimes rewrite is an optimal strategy), but I see where it comes from:
1. Most programmers when they encounter legacy code have a strong desire to rewrite it from scratch. Especially when it uses language/framework they don't know well.
2. They significantly underestimate the cost of a rewrite and either it takes much more time than estimated or a new system implements a small fraction of old features and/or re-introduces problems fixed in an old system long time ago.<p>It a cognitive bias and we can try to compensate it. Though like with any biases - usually you can see it in others, but cannot correct own behavior.
There are methods for rewriting legacy systems. Articles like this make the job of improving systems more difficult by creating an impassable set of presuppositions among non-technical stakeholders.
Agree that you should never rewrite from scratch. However, I believe that almost 100% of rewrites are not actually <i>from scratch</i>: even if not a single line is reused, there will be plenty of experience serving as a foundation.<p>I'm not implying that's always the case. Besides, in some cases, past experience is deliberately not taken into account -- I'm aware of a handful of systems written in procedural languages which performed not that great and were replaced by naive object-oriented implementations. Went really bad.
Having the developers of an existing code rewrite it using a much newer language & environment they master, with the existing code working rather adequately (but hard to extend and with mediocre performances)... is pleasant and useful.<p>Having a smaller and under pressure team of newcomers w/o any knowledge of the underlying concepts tackling a rewrite while trying to understand and fix a clunky existing code is an ordeal.
we have a data processing system in production that, for various reasons, will not scale horizontally without major work to the open source framework we're using.<p>Nobody has any appetite to fix the semi-abandoned framework, so if we want to process additional data from bigger workloads, we really have no choice but to rewrite our system.<p>Joel's right - there's a lot of pitfalls. We tried this once and it was a failure. Our 2nd attempt is going much better, though.
I suspect that instead of never rewrite from scratch, it is more never rebuild a product from scratch.<p>The problems with all these rewrites went well beyond just changing the codebases.
Before rewriting, create as many tests as possible, so you know what subtle things you broke/changed. Or foist the burden on QA/users to test.
Is Joelspolsky overrated ? There is no public code available to verify his competency like JohnCarmack. His writings are more about marketing and general technical knowledge. In my opinion he is overrated.