Caveat- I’m writing this from the perspective of a Java developer talking about refactoring/rewriting an existing Java app. It’s pretty much language agnostic though!
As developers, we have a natural tendency to want to rewrite everything we see. No two developers are likely to design systems the same way and our likely first reaction to inheriting a legacy system is to cry for the time to build it again from scratch.
There are obviously a great number of benefits for this. We get to build a fresh application however we want! The green fields and unicorns and rainbows! We can try new frameworks/languages we’ve been wanting to play with. We can avoid the pitfalls of the original application; inevitably at some point, the application has been programmed into a corner which now makes it difficult to modify in a way we want to. But we won’t make the same mistake this time!
It’s an easy sell to the business. Yes, they’ll have to use 2 systems until we cut over completely in 3/6/12 months, but what they will get will be shiny and amazing and make them so much more money and will cure world hunger and disease and make everyone like them. And this time, we’ll build it well so we can move at breakneck speeds to add even better features in quickly in the future. It’s basically going to be the greatest system the firm has ever seen.
A developer's rose tinted glasses are truly stronger than those of any other profession. All other developers are terrible, I would never make those mistakes. I can’t believe they built the system this way, anyone sensible can see it’s terrible!
Here’s my take; don’t do the rewrite. Instead, refactor the hell out of it. Beat it into a better shape with integration tests and brute force. It won’t be anywhere near as much fun, and you might not get to play with new toys, but it’s the right thing to do.
Let’s say the system in question is 2 years old. That’s 2 years of both implicit and explicit knowledge that has been built into the system. Do you have any idea how many niche and corner case bugs have been fixed in that time? I’m guessing not. But there are bugs in there that have been fixed in testing and in production, a business knowledge that is encrusted in the code. That’s irreplaceable and you’re going to have to find it all out again. You’re going to miss stuff and things are going to break if you go for a rewrite.
You’re also not as good as you think as you are, and the last developer probably wasn’t that bad. It’s hard to believe sometimes but no one goes out to write bad code. Sure there are some bad developers out there, but chances are the reason it looks like a horses backside is because those guys had some angry people shouting at them saying they need more features out in less time and it needs to be more stable but they’re taking Dave away to work on a different system and he has the most knowledge about the system.
This is going to happen to you too. I don’t know of any team who has had sufficient resource and time to build the system they want in the way they wanted to. Every program is a blob of compromises. You’ll make mistakes, in terms of functionality and you’ll write some terrible code. To believe you’re that much better is just wilfully ignorant.
Last but not least, we all suck at estimates. You think the rewrite’s going to take 3 months? Almost certainly guaranteed to take double that. We’re optimists. You’ll be held to the estimate despite the fact that you too will lose your Dave due to a priority shift, and the fact you’ll have to maintain and enhance the old system which you completely didn’t realise was going to eat 2/5ths of your time because it keeps falling over in prod and needs manual reconciliation.
Instead, you should refactor. Unless there’s a fundamental “no way around it!” flaw (e.g. it’s written in Cobol) then refactor it. Firstly, it gives you a great scapegoat; when the business wants to know why developments going slowly you can suck the air in through your teeth and talk about the unstable platform but that you’re going to fix it and save the day.
Then do it. Wrap it in a lovely bubble of integration tests, add CI and move it from releasing every 3 months to every 3 weeks to every week to every day. The business will see progress and you’ll earn some trust. Break the code up into chunks you can reason about, then wrestle it until it’s in a shape you’re comfortable with. Repeat. Bring in microservices or phase in your new HTML UI or whatever you need to do. The system will end up much more stable much faster and everyone will be much happier for it.