Rebuild or refactor? How I decide
The usual advice is never to rewrite a working product. Sometimes it is still the right call. These are the four questions I ask before choosing, and how they played out on a real product.
"Never rewrite from scratch" is good advice most of the time. A working product carries years of small fixes that nobody wrote down, and a rewrite quietly throws them away. So when I proposed rebuilding Invictus instead of improving it step by step, I owed the team a better reason than "the code is messy".
The situation
Invictus started as a minimum viable product: a tool for people who provide liquidity to crypto trading pools, built around Robinhood Chain and one family of trading protocols. It had a web app, a Telegram bot and its own data collection, all in one large package. It did its job. It proved people wanted the product.
The next version had to support seven blockchains and many more protocols, each describing the same idea in its own way, with some data needed every few seconds and some read once and kept forever. The first version was never designed for that.
The four questions
Instead of arguing about code quality, I asked four questions.
- Is the problem in the details, or in the shape? Bugs and untidy functions are details, and refactoring fixes them well. A structure built around one chain is the shape, and no amount of tidying changes it.
- How much would survive the change? If widening the structure means touching most of the code anyway, a refactor is just a slow rewrite with the old limits still in the way.
- Can users be protected while the new version is built? A rebuild should never put the people using the product at risk.
- Do we know enough to design the new shape? A rebuild without research only recreates the old problems in new files.
For Invictus the answers lined up: the problem was the shape, most code would change, and the unknowns could be researched first. So we rebuilt it, keeping the lessons of the first version but none of its code.
Two rules that kept it from going wrong
Rebuilds fail when they turn into an open-ended second project. Two rules prevented that.
- Measure before building. Storage, server size and how often data needs refreshing were measured on real data before features were written.
- Build one thing all the way through first. One feature went from the raw data all the way to the screen before anything else started. It exposed the hard integration problems early, while they were still cheap to fix.