There comes a time in any successful codebase’s lifecycle when it’s decided that it’s a legacy tire fire and needs replaced. This is a dangerous time, especially if the decision is to rewrite it from scratch in some different language or architecture. There are two main dangers: concentrating on what the old system was bad at and forgetting what it did well, and not being ruthless about the scope of the new system.

If you fix the worst parts of the old system but don’t bring across the things that it did well then your users will care more about the workflows you broke than the ones the new system enables. The 80/20 rule can fit here. Assuming 20% of the old system was causing 80% of the issues, if your new system only recreates the 20% then you’re missing a huge chunk of what’s important. With a large codebase that’s been around a while people might not even realise certain features exist and they need to consider them.

The bigger danger is a never ending project that never successfully delivers a new system. Without being ruthless about scope the architects and developers will create a complicated monster that never works. Remember Gall’s Law! If the 80/20 rule holds then you’ll want 80% of the features to be the same, no matter how you change the underlying implementation. This needs communicated and monitored throughout the project to make sure it stays on track. As with any project the clearer you are about what its purpose is the more likely it is to stay close to that purpose.

If you have any influence over the decision about a rewrite then advocate for the Strangler Fig Pattern instead of a big rewrite. This keeps things iterative and reduces risk. There will still be deeply integrated parts of the system that are going to be hard to replace. Working out how to do this in the context of the old system is harder than just starting with a blank page but you’re a lot less likely to miss important details if you have to keep the current system working.