&gt; Yes, this is the way that Guix and Leiningen and rebar3 and a bunch of other things work, and it is wonderful.<p>Even in Nix&#x2F;Guix, it&#x27;s still ideal for upstream projects to express their dependencies in terms of ranges (semver-wise), otherwise we run into the problem have either really large run-time dependency closures, or problems around e.g. wanting to use multiple (overly specified) versions of C libs within the same process.<p>As the current maintainer of Nixpkgs&#x27; Bundler-based build infrastructure, I&#x27;ve found the lockfile approach that Bundler uses to be quite frustrating - in part because Bundler&#x27;s design is antithetical to packaging, but also due to the build times and sizes of the resulting packages, compared to C libraries. (People give C a hard time wrt productivity and security and such, but when it comes to packaging, C libs are usually <i>so much easier to work with</i> than most other higher level languages.)<p>I would love to see more adoption of semver, and possibly Haskell&#x27;s PVP (<a href="https:&#x2F;&#x2F;wiki.haskell.org&#x2F;Package_versioning_policy" rel="nofollow">https:&#x2F;&#x2F;wiki.haskell.org&#x2F;Package_versioning_policy</a>). Granted, dynamic programming languages don&#x27;t have the benefit of making API breakage obvious at build time, so perhaps the best we can do in such cases -- if we want any certainty that packaged applications will actually function correctly -- is lock down every dependency version precisely per application...