> If the problem was decomposed based on ‘natural’ lines that tend away from dependencies, then the idea of treating stuff as fragments would work. But they don’t know what that means, so it doesn’t happen.

This is such a good line. Most dependencies I see in enterprise software fail miserably at this and that's why they think they need a monorepo.

I've found that people with substantial open source experience are often much better at figuring out what the 'natural' lines are because they tend to see the modules and libraries which they produce as final products. Their libraries are designed to be highly composable and cater to a broad range of use cases and systems.

The key is writing components that are generic and broadly compatible. You want to avoid putting business logic into your dependencies. Try to keep all the business logic at the highest level possible in your code.

It's very simple if you think about it; just imagine that you're a new developer on a large project, what would you want the code to look like? Most likely, you want to be able to understand what the system is doing by reading as few files as possible and you want the system's features to map to these top-level files in an obvious way.

Because when you're debugging a feature, the first thing you need to do is figure out where in the code that feature is implemented. If you can't come up with a simple answer to this, then your system is probably poorly implemented.

I strongly agree with this, but there is a danger:over-engineering, where you build a very generic module where a much simpler one will do. The key point: build the most specific module that will do the job; if it needs to be more generic for a future application, then you go back and modify it as needed, adding a second interface if necessary. Generic features that have not been used or even tested are basically garbage code.

It needs to be generic while also being as simple as possible. So you're building the module for a specific situation but leave it as open as possible for other situations without explicitly optimizing for them.