The immediate response to 20 Things You Shouldn’t Build At A Midsize SaaS was, what do you do if you HAVE built some of these things? Great question!
First, don’t panic. We’ve all been there. I have built some of these things myself – multiple CSV writers and parsers, a DateTime library, and an ORM. We are all human, and we all make mistakes from time to time.
Whether you built, or are responsible for, a bad implementation of other software, what do you do now? It depends on which of 3 buckets the implementation falls into.
It works and you don’t need to touch it
CSV parsers and writers get written a lot because they are very simple. Yes there are edge cases when it comes to escaping strings and unicode, but mostly once you have it working, it’s “fine”.
If you don’t need to touch it, don’t! Let sleeping dogs lie. Ideally put a comment in the code that the next dev should replace it with a standard library instead of expanding the code.
It works ok, but it’s incomplete
This is the biggest bucket. Implementations of DSLs, ORMs, and Frameworks usually fall into this group – the software works ok, but it is missing key features and robustness. Observability is usually extremely lacking.
This makes the software low priority tech debt. There’s opportunity cost from continuing to use it, a cost to replacing it, but no direct development costs.
Generally speaking, this is the kind of thing that gets ignored until you need a missing key feature. Then the debate between continuing with the local implementation and replacing it, resumes.
The best way to approach these situations is to look at the interfaces and requirements for the replacement software, and converge the local implementation over time. This combines regular maintenance with replacement work. As a bonus, it lowers the cognitive load on developers by making the local implementation work more like standard offerings.
It requires continuous maintenance
Some kinds of software require continuous maintenance. When you write your own, you have to do all the maintenance yourself.
Scripting languages are a wonderful source of Halting Problem issues. Your customers will be excellent at creating scripts that will never exit and will consume resources until the server restarts. The more successful you are, the worse the problem will become.
I saw a SaaS with 2 full time developers working to close all of the ways that customers were accidentally creating infinite loops with their homegrown scripting language.
I worked at a company using objective-c which had extended Apple’s compiler. This was back in the days of installed, on-prem, software. Every time Apple had a release, we had to warn customers not to upgrade until we could re-extend the compiler, recompile, and ship the code.
When you encounter implementations that require continuous maintenance, you have to start working to remove them immediately. The longer they remain, the more entrenched they become. The sunk cost fallacy will work against you in strange and insidious ways.
Iterative removal is the only real option in these cases.
No matter which bucket the badly implemented software falls into, the first step is always to recognize the problem. If there’s already an implementation, you shouldn’t write your own without a good reason.