Rewriting applications from scratch is a bad idea
There are many good reasons to rewrite a legacy application, but most of the time, the cost outweighs the benefits.
Many developers, including myself, can live with a legacy application for only so long before they want to kill it, burn it with fire, and rebuild it from the ground up. The code is so hard to follow and understand, hundred-lines methods, unused variables, conditionals conditioning conditionals on the different levels. It's so terrible Sandi's squint test would make you dizzy.
Why rewrites are so alluring
You get to use the newest and shiniest tools.
It's hard not to wish for a rewrite when you see features you could improve by just using a new best practice, framework, or package. Why would you struggle with shovels and hammers when you have access to all kinds of shiny-new tools that can do the same thing (and more) faster and better?
You have all the facts
Looking through the codebase and its history, we can see all the ways in which the previous developers went wrong.
The clients themselves have more experience and know exactly what they want - no more guess-work.
Rewriting the app will be a piece of cake done in a heartbeat!
Easier to write tests
Writing tests for legacy applications lacking them is painfully hard. Not only are there countless dependencies and execution paths to follow, often times you don't even know what to test! You're left playing the detective, carefully following every method guessing what it's supposed to do. When you start from scratch, you get to test your own code, which is a million times easier.
Why are rewrites a bad idea
Rewrites are expensive
The application won't rewrite itself. You have to pour hours and hours into getting it to the point where, well, it does pretty much what it was doing before, maybe a little better.
One would make a good argument by saying, "you'll be losing the same or even more time and money by not rewriting it, due to the inability to ship features as fast”.
That is true. Holding a legacy codebase together, fixing bugs, and shipping new features at the same time is no walk in the park. You can't be rolling out feature after feature like you used to. But at least it's not impossible; which is the second point:
Harder to release new features
When you go on a rewrite, unless a big team is involved, you are pretty much unable to release major features for months. Depending on the nature of the business, responding to users and shipping new features might be critical. Your client might not even be in business by the end of the rewrite.
You don't really have all the facts
After years and years of changes, no one knows precisely how the app reacts in every situation, not even your clients. Go ahead, ask them. They might have a general idea of everything works, but most of the time you are left with many unknowns. Go into a full rewrite unprepared, and you will waste hours and hours on client communication.
DEV: How does this work?
DEV: What about that?
CLIENT: Wait, what? I didn't even know we had that feature.
DEV: Oh, well...
Client relationship damage
Let's say you get your client to agree on all the costs of the rewrite. You promise them all of this will be worth it. The app will be faster, bug-free, better designed, and easier to extend, all that good stuff.
If there's one thing we know about software development is that at some point, something somewhere will go wrong: the server, the database, a misconfigured service, some feature misunderstanding, etc. No matter how much you plan, something somewhere will go wrong; it's like a law of nature.
When that happens, your client will start questioning the decision to rewrite. Even though the new application is 10x more enjoyable to work with, they don't know or value that. They don't care if you are using the latest and greatest tools, best practices, frameworks, and packages.
All your client knows is they agreed to spend a ton of money and precious time on something that looks and functions quite the same. Every hiccup you go through will cause damage to your relationship.
When you should consider a rewrite
Apart from the case in which the application is small and straightforward, and you can rewrite it from scratch in just a few months, there are two more situations when a complete rewrite can be a good idea:
When shipping new features is not a priority
When business is steady, with most work revolving around customer support and a few bugs here and there, if there's no time pressure, and you want to do a rewrite for performance reasons and/or stay up to date with the latest technologies.
When going for a completely different approach
The business has been great, the clients are happy, and the current application is well-tested and crafted, but it has gotten a bit old, and you want to try a fresh approach to attract new customers.
Basecamp is the best example I know. Every few years, they completely rewrite and launch a new version of their product. New customers are coming in for the shiny new approach, while the old ones are given the choice to upgrade or to stick with their current version. Everyone is happy.
Having to work on legacy codebases sucks. You are terrified when clients ask you to add a new feature. You feel like you can't touch anything without breaking something else in some obscure corner of the codebase. The only reasonable solution you see is to give up and rewrite the whole thing — anything to make the madness stop. Hell, sometimes you feel you'd be willing to do it for free in your own spare time.
But sadly, rewriting is rarely a good idea. There are too many unknowns for it to be a quick & easy process, you have to put a hold on launching new features, you risk damaging your relationship with your clients, and the time and money invested might never be earned back.
Refactoring, on the other hand, might be just enough to save you.