All laws

§ 97Maintainability

One-Version Rule

When consumers may choose which version of a shared dependency to use, each choice becomes a conflict for someone who never made it.

Google

Keep in mind

Treat every second version as a debt with an owner and an end date

What to do

Keep one version of every shared dependency, internal or third-party, and do each upgrade as one change that moves every caller. When an upgrade cannot land in one step, allow a second version only under a different name, with an owner and an end date, and delete it when the date comes. Do not let a team fork or pin a shared library on its own. Where projects have genuinely different security, legal or release requirements, split them into separate repositories, but hold each one to a single version per dependency.

Why it happens

Two components that pin different versions of the same library each work on their own. A program that comes to depend on both gets a link failure at best, or one copy picked at random at runtime, and the team that pays is the one that combined them, not the ones that pinned. Every extra version also adds another place a security fix or an upgrade has to land, and the copies drift apart until moving off the old one is a project of its own. Hiding the second copy, by shading or renaming, does not make the conflict go away. Allowing exactly one version per dependency removes the choice, so an upgrade can be done once for every caller, and adding a dependency no longer breaks a bystander through a version conflict.

When it stops applying

Semantic Import Versioning: where no one owns every caller, as across an open-source ecosystem, nobody can make the single change that moves everyone, so letting incompatible major versions live side by side under different import paths lets each caller upgrade on its own schedule and accepts the duplicate copies as the price, which is the approach Go modules take.

Source

Titus Winters, "Version Control and Branch Management", in Winters, Manshreck & Wright, Software Engineering at Google (O'Reilly, 2020), ch. 16 — "For every dependency in our repository, there must be only one version of that dependency to choose.", shading solutions that "work neither in theory nor in practice", and "What is important is not whether we focus on monorepo; it's to adhere to the One-Version principle to the greatest extent possible"; Google Open Source, The One Version Rule (third-party policy) — "There may only be one version of a package in `//third_party`." The counter-force is Russ Cox, Semantic Import Versioning (research!rsc, 2018) — "to make it possible to upgrade the clients of that package one at a time and still have a buildable result".

Read the source

Mark: Public domain · Wikimedia Commons

Cite this

Hammurabi, § 97, “One-Version Rule.” https://kanywst.github.io/hammurabi/laws/one-version-rule/

BibTeX
@misc{hammurabi-one-version-rule,
  title  = {One-Version Rule},
  author = {{Hammurabi contributors}},
  note   = {Hammurabi, § 97},
  url    = {https://kanywst.github.io/hammurabi/laws/one-version-rule/}
}

Text under CC BY-SA 4.0: credit Hammurabi and link the article.

Related laws

Suggest a correction on GitHub