
Things You Should Never Do (2000) - HugoDias
https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/
======
hn_throwaway_99
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 _always_ 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.

If anything, what should be warned against is _big bangs_. 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.

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.

~~~
goto11
The more experience I get, the more I think Joel was right. Developers want to
believe rewrite-from-scratch can succeed because green-field development is
easier and more fun than slowly refactoring inscrutable legacy code. But long
before the rewrite project achieve feature parity with the original, it is
already marred by the same issues that motivated the rewrite. Because the
dysfunction which led to the original code turning into a mess have not been
addressed.

"But we are smarter than those other guys who wrote this mess" \- if that is
the case, you should be smart enough to fix the mess.

~~~
Wowfunhappy
I think I mostly agree with your take, but if I could defend the
counterargument for a moment, there exist stronger cases for a rewrite than
"we're smarter than those other guys." Namely, what happens if your
requirements have fundamentally changed?

Classic Mac OS was written at a time when computers had kilobytes of memory
and black and white graphics. It was not designed for multi-tasking, because
at the time it was written, the world had insufficient hardware to make multi-
tasking practical. It was not designed for networking, because the internet
mostly did not exist at the time. It was not designed for security, because
computers were a less important target for criminals, and no internet meant
far fewer exploit vectors.

All of these features were post-facto bolted onto Mac OS, and the result was
an unstable mess. It was ultimately a full OS rewrite that fixed the platform.

\---

I'll make a separate case too, for a rewrite I _wish_ would happen: it's all
well and good for Slack to build their client in Electron as a small startup
that needs to experiment and iterate quickly. However, Slack is now a
reasonably-sized public company, and they (should) have a stable product that
will not undergo rapid changes.

Now would be an excellent time for Slack to rewrite their client to be a
native app on each of the major platforms. They have the resources to create a
snappy, performant app that more customers will enjoy using.

~~~
goto11
But didn't Apple actually attempt a full rewrite of the Mac OS which
eventually failed? So instead they bought an already working OS and adapted it
for their purpose.

~~~
Wowfunhappy
Well, as I'm thinking of it NextStep was still effectively a "rewritten from
scratch" OS—it just happened to get written outside of Apple.

~~~
goto11
That is not what Joel means by rewriting from scratch. NextStep was not
written to replace Mac OS, it was just later adapted into that purpose. It is
a completely different scenario.

------
mojuba
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).

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, _no downsides whatsoever_
because otheriwse the same month I would have spent fixing maybe 4 or 5
multithreading bugs in the old codebase.

Anyway, never say "never do X" because you are most likely wrong.

~~~
gfodor
I think this advice is not relevant if you are on a project where it's
feasible for a single developer to re-write it in a month. Burning a month on
a failed re-write is certainly worth the risk if you take a run at it.

For projects where there are several devs going to be working on the re-write
for a long time, it almost certainly is a sign that the 'legacy' code has way
more knowledge embedded in it than it might seem. Having been on the death
march of a re-write before I think the signs are usually obvious when you're
in one scenario or the other.

~~~
perl4ever
>I think this advice is not relevant if you are on a project where it's
feasible for a single developer to re-write it in a month

The implication is that is can be non-obvious if something is potentially that
sort of project, as it originally was a large undertaking. I mean, you can
assume it's a fake story, but they said it wasn't originally a one person, one
month thing.

I don't know that it implies the person who rewrites something is a super-
genius, it's just that sometimes a new perspective or tools allow a really
amazing improvement.

~~~
gfodor
Yeah I was referring to the posterior - eg if your project _could_ be
rewritten by one person in a month (unbeknownst to you beforehand) then the
advice is irrelevant. Hence it’s worth attempting a re-write in some cases to
determine that, and failing fast.

------
542458
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.

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.

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).

For reference, Twitter has done a total rewrite of their large codebase, and
lived to tell the tale.

~~~
m12k
Yeah, it's probably closer to things like fiddling with assembly, manual
thread syncing and rolling your own crypto - it's not that you should never do
it, but unless you're very, very sure what you're doing and why, it's probably
a bad idea.

------
mjw1007
« 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 »

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.

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.

~~~
tedunangst
Firefox has less market share today than Netscape did at the time this was
written.

~~~
sukilot
But the market share was lost to a "rewrite" by a competitor.

------
katzgrau
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).

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.

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).

------
projektfu
Always important to mention the alternative, a "Strangler Fig Application",
also known as the strangler pattern.

[https://martinfowler.com/bliki/StranglerFigApplication.html](https://martinfowler.com/bliki/StranglerFigApplication.html)

------
ChicagoDave
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.

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.

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.

~~~
HenryBemis
> They have things to sell and customers to support...today.

Deau ex Agile.. knock out one "thing" at a time and let's keep loading the
backlog for the next features/etc to be upgraded/rewritten. Tbh in banking I
see very few rewrites, most banks (that make their own applications) don't fix
it unless it breaks down. They only bother in massive upgrades where modules
are rewritten, or an application is replaced one module at a time.

------
atsaloli
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.

In his book "Code Simplicity", Max has a checklist (summarized in point 4 of
[https://techbeacon.com/app-dev-testing/rewrites-vs-
refactori...](https://techbeacon.com/app-dev-testing/rewrites-vs-
refactoring-17-essential-reads-developers)) -- and that's the checklist
referred to in the InfoQ interview.

~~~
atsaloli
Here is the link to the InfoQ interview:
[https://www.infoq.com/news/2018/01/q-a-max-kanat-
alexander/](https://www.infoq.com/news/2018/01/q-a-max-kanat-alexander/)

------
dlbucci
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.

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.

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.

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...)

~~~
rubber_duck
Rewriting anything complex and actively used from scratch is not a good idea
and the problems have been hashed out may times.

Having said that, angularjs and coffescript is a terrible software stack in a
dead ecosystem, the best course of action is probably incremental rewrite -
React is really good at that because it starts out as a small rendering
library and you can incrementally replace stuff like routing etc.

~~~
buu700
For that example, I would just use Decaffeinate to migrate to ES6, upgrade to
TypeScript + AngularJS 1.5+ best practices as OP did, and then follow the
official AngularJS -> Angular migration path.

Considering they're two entirely different frameworks, Google did a good job
creating a usable compatibility layer. This allows a relatively painless "ship
of Theseus"-style transition where you have a combination of Angular and
AngularJS components interacting with each other, until eventually it's just
Angular components and you can drop AngularJS from the build.

------
S_A_P
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.

------
justin_oaks
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.

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.

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.

------
almostdeadguy
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.

------
dang
From the three dozen or so previous submissions, the actual discussions seem
to be:

2013
[https://news.ycombinator.com/item?id=6327021](https://news.ycombinator.com/item?id=6327021)

2012
[https://news.ycombinator.com/item?id=3624830](https://news.ycombinator.com/item?id=3624830)

2012 (a bit)
[https://news.ycombinator.com/item?id=3449953](https://news.ycombinator.com/item?id=3449953)

2009
[https://news.ycombinator.com/item?id=608431](https://news.ycombinator.com/item?id=608431)

------
winrid
A better way to put it IMO is that you should never go dark on your customers
during a rewrite.

------
jonnycat
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.

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.

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."

~~~
insertnickname
Refactoring is different from rewriting.

~~~
perl4ever
I think the above implies that it is different, because it is a subset?

------
dharmab
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.

------
citrin_ru
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.

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.

------
larsenwolf
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.

------
myth2018
Agree that you should never rewrite from scratch. However, I believe that
almost 100% of rewrites are not actually _from scratch_ : even if not a single
line is reused, there will be plenty of experience serving as a foundation.

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.

------
natmaka
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.

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.

------
fnord77
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.

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.

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.

------
MattGaiser
I suspect that instead of never rewrite from scratch, it is more never rebuild
a product from scratch.

The problems with all these rewrites went well beyond just changing the
codebases.

------
Tempest1981
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.

------
bachmeier
Relevant links:

[https://medium.com/@herbcaudill/lessons-from-6-software-
rewr...](https://medium.com/@herbcaudill/lessons-from-6-software-rewrite-
stories-635e4c8f7c22)

And this DHH talk (transcript) [https://businessofsoftware.org/2015/10/david-
heinemeier-hans...](https://businessofsoftware.org/2015/10/david-heinemeier-
hansson-rewrite-basecamp-business-of-software-conference-video-dhh-bos2015/)

------
makstaks
I'm digging through some legacy code, feeling better about it after reading
this.

------
focus2020
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.

------
pictur
I think rewriting a project is an endless curse.

------
aronpye
TLDR

Don’t re-write from scratch, refactor instead.

