One-size-fits-all products get increasingly hard to maintain and extend.
Let's say you have a successful product for one use case.
You want to add a new use case that is partially or largely overlapping with the first.
What do you do?
You extend the first product to also accommodate the second use case.
It would be insane to build a whole new product for the related use case!
Software is expensive and there's a lot of baseline investment necessary to get a simple minimal product.
In addition, products take time and effort to distribute, why not draft off the existing distribution?
This is a totally reasonable thing to do, especially if the overlap is significant.
But there is a downside: more complexity.
There's more conditions to maintain and test.
There are more things for the end-user to potentially have to be aware of and reason about.
Then it happens again. You have a 2 use case product and see a third that is adjacent.
It's not quite as much overlap as 1 and 2 had, but the initial product already has more momentum and investment so it's more obvious to build on top of it.
This can continue, with each incremental step locally making sense.
But the complexity growth is not linear, it's combinatorial.
Every pair of features the user has to potentially be able to reason about.
When adding a feature, the number of conditions and edge cases to reason about explodes.
The explosion of complexity makes the product hard to understand for any single use case, and also extremely expensive to maintain and extend.
How can you avoid this?
Building an open-ended system with a small number of open-ended primitives to combine.
Can you imagine if software were cheap to build and distribution were cheap?
You could have a single experience for a single use case, doing exactly what the user needed, no more, no less.