Right there with you. I take my misery and suffering in moderation, though, and since I think you might too, this design guide could help you keep most of your hair. But the real focus here is general package management design principles and domain constraints, and how they may apply in different languages. Package management is awful, you should quit right now Package management is a nasty domain. On the surface, it seems like a purely technical problem, amenable to purely technical solutions. And so, quite reasonably, people approach it that way. And — happy day! You will have a bad time. Package management is at least as much about people, what they know, what they do, and what they can reasonably be responsible for as it is about source code and other things a computer can figure out. Both sides are necessary, but independently insufficient. Bad ones dump the fetched source code into a global, unversioned pool GOPATH , then cackle maniacally at your fervent hope that the cumulative state of that pool makes coherent sense. That means specifying, retrieving, updating, arranging on disk, and removing sets of dependent source code, in such a way that collective coherency is maintained beyond the termination of any single command. Its output — which is precisely reproducible — is a self-contained source tree that acts as the input to a compiler or interpreter. SPMs are systems for users, PDMs are systems for developers, and LPMs are often sorta both. PDMs, on the other hand, are quite content without LPMs, though in practice it typically makes sense to bundle the two together. That bundling, however, often confuses onlookers into conflating LPMs and PDMs, or worse, neglecting the latter entirely. You will have a bad time. PDMs are pretty much at the bottom of this stack. Fortunately, describing their responsibilities is pretty easy. Remember that thing about how package management is just as much about people as computers? There is a natural tension between the need for absolute algorithmic certainty of outputs, and the fluidity inherent in development done by humans. That tension, being intrinsic and unavoidable, demands resolution. Providing that resolution is fundamentally what PDMs do. Their final outputs are phase zero of a compiler or interpreter, and while the specifics of that vary from language to language, each still presents a well-defined target. As with many problems in computing, the challenge is figuring out how to present those machine requirements in a way that fits well with human mental models. In truth, not just FLOSS — code ecosystems within companies are often a microcosm of the same. Sorting wheat from chaff, and my own feelings from fact, will also take time. The themes here are time, risk, and uncertainty. Some uncertainties may be heightened or lessened on some projects, but we cannot make them disappear. They are natural constraints. OK, OK, I get it: creating software is full of potentially dangerous unknowns. I like to think of the solution through an analogy from public health: harm reduction. A little while back, wrote a lovely piece called. This is the mentality we must adopt when building a practical tool for developers. Taking risks is a necessary part of development. The PDM use case is for a tool that encourages developers to reduce uncertainty through wild experimentation, while simultaneously keeping the project as stable and sane as possible. Like a rocket with an anchor! Under different circumstances, this might be where I start laying out use cases. Understanding what state we have, as well as when, why, and how it cha