Hacker News new | ask | show | jobs
by PragmaticPulp 2400 days ago
Rarely.

Complete rewrites invariably take far longer than expected. That old codebase, however messy, includes almost two decades of decisions, lessons learned, special cases, and tribal knowledge. The rewrite will surface each one of those issues again over time.

Second, you need to retrain everyone on the new software. Surely the new UI/UX will be better, but how many people have years of accumulated knowledge in the old software? It's not just about retraining. Some of the old users will hate the new system just because they don't like change. It may be objectively better, but if it makes everyone complain to your boss's boss every day because 100 people had to relearn a new system, is it really better for the org?

Third, the old software is certainly more complex than you can see from the surface. At minimum, you should start by adding analytics to the existing codebase so you can see which features are used. You will be surprised to learn that people use the software much differently than you would have guessed.

Fourth, you're not off the hook for maintaining and supporting the old software during the rewrite. If a new, urgent feature request comes in and the rewrite is too far behind schedule to be ready in time (it will be behind schedule, guaranteed) then you must still service the old codebase in the interim. This is a constant tax on productivity that slows down rewrites, unless you can justify two completely independent teams.

My advice: Make an effort to calculate the ROI on the rewrite. Include the overhead of maintaining the current system during the rewrite, as well as the costs of retraining everyone who used the old software. If you can't reduce overall costs after a few years with a rewrite, it's hard to justify. It's an unpopular opinion with programmers, but some times it really does make sense to continue to throw developers at an old codebase instead of rewriting from scratch.

If you must rewrite, look for a way to rewrite incrementally. For example, writing a new front-end for the existing back-end with a modular API translation layer. Ship the new front-end, work out the bugs, and then work on replacing the back-end later. Depending on the codebase, you may even be able to write a backend shim and slowly replace individual endpoints and rework the API one feature at a time until the old backend can be fully deprecated.