After re-reading https://shopify.engineering/a-packwerk-retrospective I’m left with a lot of questions about what good modularity looks like. I’m not looking to center this conversation around Packwerk or the tooling but more about the concepts it brought to the conversation.
… [Packwerk] was being used to ensure that packages communicated via blessed entrypoints, whereas its original purpose was to define and enforce a dependency graph. Package A using package B’s code (even its public API) is not acceptable if package A doesn’t depend on B, yet we found developers were focusing on the design of their APIs over the dependencies in their code. This was drawing attention away from the problem the tool had been created to solve.
The API design aspects of this really hit me because I feel like I’ve fallen into this trap too; it’s really nice to define an API between slices of your app. It feels like you’re doing good work.
So I wanted to kick the discussion off by asking, what are some actionable practices we can adopt to make healthy monoliths with healthy relationships between its parts?
More specific to packwerk, I have found that for some packages I focus on dependencies (or its cousins, layers and visibility) and for others I focus on privacy / the API, for some it is very quickly about both.
“It feels like you’re doing good work.” - do you not think it is good work?
To answer your question using the above: Try, learn, apply, iterate. If you’re faced with an application where a lot of past decisions have brought you to a situation where you know you need to make some big changes, then you won’t get away without all of the above. Explore whether a tool like packwerk helps, explore whether privacy or dependency helps. If it does, use it.
I’d be interested to hear what the consequences of this was for you. Did you end up creating APIs or slices that were not useful? What were your takeaways?