diff --git a/lib/versioning/cargo/readme.md b/lib/versioning/cargo/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..cadd50a919f7b48d2ea09b3a5265274f4fe70d24
--- /dev/null
+++ b/lib/versioning/cargo/readme.md
@@ -0,0 +1,31 @@
+# Cargo versioning
+
+## Documentation and URLs
+
+https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
+
+## What type of versioning is used?
+
+Cargo uses [Semantic Versioning 2.0](https://semver.org).
+
+## Are ranges supported? How?
+
+Cargo supports ranges in a similar manner to npm, but not identical. The important differences are:
+
+##### Use of commas
+
+Multiple version requirements can also be separated with a comma, e.g. `>= 1.2, < 1.5`. We interpret this to mean AND.
+
+##### No exact versions unless using equals =
+
+In Cargo, `1.2.3` doesn't mean "exactly 1.2.3", it actually means `>=1.2.3 <2.0.0`. So this is like the equivalent of `^1.2.3` in npm.
+
+## Range Strategy support
+
+Cargo versioning should support all range strategies - pin, replace, bump, extend.
+
+## Implementation plan/status
+
+- [x] Add cargo2npm and npm2cargo functions to leverage existing npm semver logic
+- [x] Exact version support
+- [x] Range support
diff --git a/lib/versioning/composer/readme.md b/lib/versioning/composer/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..f545f56c70773ae6948c16e3329c3f103af9e542
--- /dev/null
+++ b/lib/versioning/composer/readme.md
@@ -0,0 +1,32 @@
+# Composer versioning
+
+## Documentation and URLs
+
+https://getcomposer.org/doc/articles/versions.md
+https://packagist.org/packages/composer/semver
+https://madewithlove.be/tilde-and-caret-constraints/
+https://semver.mwl.be
+
+## What type of versioning is used?
+
+Composer uses Semver-like versioning, however some package authors may use versions that are not completely valid, e.g. `1.2` instead of `1.2.0`.
+
+## Are ranges supported? How?
+
+Composer supports ranges in a similar manner to npm, but not identical. The main difference is with tilde ranges.
+
+Tilde ranges with "short" versions are different to npm. e.g.
+
+`~4` is equivalent to `^4` in npm
+`~4.1` is equivalent to `^4.1` in npm
+`~0.4` is equivalent to `>=0.4 <1` in npm
+
+## Range Strategy support
+
+Composer versioning should support all range strategies - pin, replace, bump, extend.
+
+## Implementation plan/status
+
+- [x] Add composer2npm and npm2composer functions to leverage existing npm semver logic
+- [x] Exact version support
+- [x] Range support
diff --git a/lib/versioning/docker/readme.md b/lib/versioning/docker/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..21c5db074798e68812c861ec343039cc86e67402
--- /dev/null
+++ b/lib/versioning/docker/readme.md
@@ -0,0 +1,35 @@
+# Docker versioning
+
+## Documentation and URLs
+
+Docker doesn't really use _versioning_, but it supports "tags" and these are usually used by Docker image authors as a form of versioning.
+
+This "versioning" implementation is essentially a creation of Renovate to handle the default _conventions_ used in tagging most images. In particular, it treats the text after the first hyphen as a type of platform/compatibility indicator.
+
+For example, many images include images with the "-alpine" suffix, e.g. the offical `node` Docker image includes tags like `8.14.0-alpine` which is _not_ compatible with `8.14.0` or `8.14.0-stretch`. This means users only want/expect upgrades to `8.15.0-alpine` and not `8.15.0` or `8.15.0-stretch`.
+
+Similarly, a user with `8.14` expects to be upgraded to `8.15` and not `8.15.0`.
+
+## What type of versioning is used?
+
+It's pretty "wild west" for tagging and not always compliant with semver. Docker versioning in Renovate should do a best effort to accept and sort semver-like versions.
+
+## Are ranges supported? How?
+
+Yes and no. In theory, a tag of `8.15` should be like `>=8.15.0 <8.16.0`. In practice, there is nothing that enforces that the latest `8.15` code matches exactly with the latest `8.15.x` tag. e.g. `8.15` may not be the same as `8.15.0`, but it usually should be. Also, `8.15` is technically a version and not a range.
+
+## Range Strategy support
+
+We may be able to "pin" from range-like tags like `8.15` to semver-like tags like `8.15.0` but we should probably work out a way to compare the sha256 hashes before pinning.
+
+Otherwise, we can support "replace" strategy.
+
+"Bump" strategy and "extend" strategies are not applicable.
+
+## Implementation plan/status
+
+- [x] Compatibility check between tag suffixes
+- [x] Upgrade semver tags (e.g. `8.14.0` to `8.15.0`)
+- [x] Upgrade range-like tags (e.g. `8.14` to `8.15`)
+- [x] Allow non-semver-compatible leading zeroes, e.g. `16.04.0` to `16.04.1`
+- [x] Support getDigest for pinning and updating tag digests
diff --git a/lib/versioning/hashicorp/readme.md b/lib/versioning/hashicorp/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..cb1f1e560346108f86799b906ac469605508996a
--- /dev/null
+++ b/lib/versioning/hashicorp/readme.md
@@ -0,0 +1,25 @@
+# Hashicorp versioning
+
+## Documentation and URLs
+
+https://www.terraform.io/docs/configuration/terraform.html#specifying-a-required-terraform-version
+
+This versioning syntax is used for Terraform only currently.
+
+## What type of versioning is used?
+
+Hashicorp uses [Semantic Versioning 2.0](https://semver.org).
+
+## Are ranges supported? How?
+
+Hashicorp supports a subset of npm's range syntax.
+
+## Range Strategy support
+
+Hashicorp versioning should support all range strategies - pin, replace, bump, extend.
+
+## Implementation plan/status
+
+- [x] Add hashicorp2npm functions to leverage existing npm semver logic
+- [x] Exact version support
+- [x] Range support
diff --git a/lib/versioning/loose/readme.md b/lib/versioning/loose/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..571a8c4fa7106156ac12054ef9de39e23b51bfef
--- /dev/null
+++ b/lib/versioning/loose/readme.md
@@ -0,0 +1,23 @@
+# loose versioning
+
+This "loose" is specific for Renovate and created for instances where no strict versioning is in place. It works like semver if semver-compliant versions are suppolied, but otherwise is "best effort".
+
+## Documentation and URLs
+
+None
+
+## What type of versioning is used?
+
+None, but it's semver-like.
+
+## Are ranges supported? How?
+
+No
+
+## Range Strategy support
+
+No
+
+## Implementation plan/status
+
+- [x] Best effort parsing and sorting
diff --git a/lib/versioning/maven/readme.md b/lib/versioning/maven/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..0ffb3427f40fb59035472c93cb130c0b40fd433b
--- /dev/null
+++ b/lib/versioning/maven/readme.md
@@ -0,0 +1,24 @@
+# Maven versioning
+
+## Documentation and URLs
+
+https://maven.apache.org/pom.html#Dependency_Version_Requirement_Specification
+https://octopus.com/blog/maven-versioning-explained
+https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html
+
+## What type of versioning is used?
+
+Maven's versioning is similar to semver but also very different in places. It's specified by Maven itself.
+
+## Are ranges supported? How?
+
+Yes, Maven uses its own special syntax for ranges.
+
+## Range Strategy support
+
+npm versioning should support all range strategies - pin, replace, bump, extend.
+
+## Implementation plan/status
+
+- [x] Exact version support
+- [ ] Range support (#2986)
diff --git a/lib/versioning/node/readme.md b/lib/versioning/node/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..03a68d8f03815cfc6e79e47dde1993559deb4b1d
--- /dev/null
+++ b/lib/versioning/node/readme.md
@@ -0,0 +1,24 @@
+# node versioning
+
+This "node" versioning is nearly identical to npm's semver except that it makes sure to strip "v" prefixes from exact versions when replacing.
+
+## Documentation and URLs
+
+https://semver.org/
+
+## What type of versioning is used?
+
+Node.JS's versioning complies with [Semantic Versioning 2.0](https://semver.org).
+
+## Are ranges supported? How?
+
+Same as npm.
+
+## Range Strategy support
+
+Same as npm
+
+## Implementation plan/status
+
+- [x] Strip v prefix
+- [ ] Support Node.js-specific "stable" awareness
diff --git a/lib/versioning/npm/readme.md b/lib/versioning/npm/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..29abebfc71459dce19e782fba2d55f91f703a30b
--- /dev/null
+++ b/lib/versioning/npm/readme.md
@@ -0,0 +1,25 @@
+# npm versioning
+
+## Documentation and URLs
+
+https://semver.org/
+https://www.npmjs.com/package/semver
+https://docs.npmjs.com/about-semantic-versioning
+https://semver.npmjs.com/
+
+## What type of versioning is used?
+
+npm has the most well known/widely used implementation of [Semantic Versioning 2.0](https://semver.org).
+
+## Are ranges supported? How?
+
+npm's semver implementation supports a large number of range operators.
+
+## Range Strategy support
+
+npm versioning should support all range strategies - pin, replace, bump, extend.
+
+## Implementation plan/status
+
+- [x] Exact version support
+- [x] Range support
diff --git a/lib/versioning/pep440/readme.md b/lib/versioning/pep440/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..04e96b5af184737bab36b5b1f9dd3ab7cdc08059
--- /dev/null
+++ b/lib/versioning/pep440/readme.md
@@ -0,0 +1,22 @@
+# PEP 440 versioning
+
+## Documentation and URLs
+
+https://www.python.org/dev/peps/pep-0440/
+
+## What type of versioning is used?
+
+PEP 440 is part of the Python project, and its versioning is independent of others such as semver.
+
+## Are ranges supported? How?
+
+Ranges are supported, with a proprietary syntax.
+
+## Range Strategy support
+
+PEP 440 versioning should support all range strategies - pin, replace, bump, extend.
+
+## Implementation plan/status
+
+- [x] Exact version support
+- [x] Range support
diff --git a/lib/versioning/ruby/readme.md b/lib/versioning/ruby/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..3a33a0cb683e53392df985ae95ca27bc5e390721
--- /dev/null
+++ b/lib/versioning/ruby/readme.md
@@ -0,0 +1,24 @@
+# Ruby versioning
+
+## Documentation and URLs
+
+https://guides.rubygems.org/patterns/
+https://bundler.io/v1.5/gemfile.html
+https://www.devalot.com/articles/2012/04/gem-versions.html
+
+## What type of versioning is used?
+
+> The RubyGems team urges gem developers to follow the Semantic Versioning standard for their gem’s versions.
+
+## Are ranges supported? How?
+
+Range syntax is similar to npm's but not identical. The main difference is the use of "pessimistic" greater than or equals: `~>`
+
+## Range Strategy support
+
+Ruby versioning should support all range strategies - pin, replace, bump, extend.
+
+## Implementation plan/status
+
+- [x] Exact version support
+- [x] Range support
diff --git a/lib/versioning/semver/readme.md b/lib/versioning/semver/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..bd3388edc530fda0da331732343277f0978f0cc9
--- /dev/null
+++ b/lib/versioning/semver/readme.md
@@ -0,0 +1,21 @@
+# Semver versioning
+
+## Documentation and URLs
+
+https://semver.org/
+
+## What type of versioning is used?
+
+This is a strict/independent implementation of [Semantic Versioning 2.0](https://semver.org). It has been developed to be used in situations where exact-only semver support is needed and not npm's extended semver implementation including ranges.
+
+## Are ranges supported? How?
+
+Semver deliberately doesn't support any ranges, as per the spec
+
+## Range Strategy support
+
+Not applicable
+
+## Implementation plan/status
+
+- [x] Exact version support
diff --git a/test/versioning/versioning-readmes.spec.js b/test/versioning/versioning-readmes.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..6cc98995da753d2280f91ad93ecbc1505f87f866
--- /dev/null
+++ b/test/versioning/versioning-readmes.spec.js
@@ -0,0 +1,28 @@
+const fs = require('fs-extra');
+
+describe('versioning readmes', () => {
+  it('has same questions for all version schemes', async () => {
+    const managers = (await fs.readdir('lib/versioning')).filter(
+      item => !item.includes('.')
+    );
+    let expectedHeaders;
+    for (const manager of managers) {
+      let readme;
+      try {
+        readme = await fs.readFile(
+          'lib/versioning/' + manager + '/readme.md',
+          'utf8'
+        );
+      } catch (err) {
+        // ignore missing file
+      }
+      if (readme) {
+        const headers = readme
+          .match(/\n## (.*?)\n/g)
+          .map(match => match.substring(4, match.length - 1));
+        expectedHeaders = expectedHeaders || headers;
+        expect(headers).toEqual(expectedHeaders);
+      }
+    }
+  });
+});