Retrospective: The Rewrite That Didn't Ship
1 min read
The context
A legacy API built on Express.js, 15k LOC, lots of tech debt. The team was frustrated with the codebase and convinced a rewrite was the only way forward.
What happened
- Month 1: Planning the new architecture
- Month 2: Building the foundation
- Month 3: Feature parity — discovered 23 undocumented behaviors
- Month 4: Bug fixing and scope creep
- End of Month 4: Canceled. Too far behind, too many unknowns.
What we should have done
Strangler Fig pattern: Replace pieces incrementally. Route new features to new code, gradually migrate old routes. No big bang.
Cost of delay analysis: The rewrite had an 8-month break-even. Legacy was slow but working. The math didn’t support it.
What I learned
The only good reason to rewrite code is if the current architecture prevents you from shipping a specific, valuable feature. “It’s messy” is not a reason. “We can’t add real-time collaboration without a fundamentally different data model” is.