diff --git a/lib/datasource/docker.js b/lib/datasource/docker.js
index 021427bb3b0ba30350bd4a97c16ed62720b79c0b..391a585fe90b4c7ef43f7ce9534df8503fc08fbb 100644
--- a/lib/datasource/docker.js
+++ b/lib/datasource/docker.js
@@ -102,6 +102,17 @@ function extractDigestFromResponse(manifestResponse) {
   return manifestResponse.headers['docker-content-digest'];
 }
 
+/*
+ * docker.getDigest
+ *
+ * The `newValue` supplied here should be a valid tag for the docker image.
+ *
+ * This function will:
+ *  - Reconstruct the tag using newValue and tagSuffix
+ *  - Look up a sha256 digest for that tag on its registry
+ *  - Return the digest as a string
+ */
+
 async function getDigest(config, newValue) {
   const { dockerRegistry, depName, tagSuffix } = config;
   logger.debug(`getDigest(${dockerRegistry}, ${depName}, ${newValue})`);
@@ -265,6 +276,22 @@ async function getTags(registry, repository) {
   }
 }
 
+/*
+ * docker.getPkgReleases
+ *
+ * A docker image usually looks something like this: somehost.io/owner/repo:8.1.0-alpine
+ * In the above:
+ *  - 'somehost.io' is the registry
+ *  - 'owner/repo' is the package name
+ *  - '8.1.0-alpine' is the tag
+ *  - 'alpine' is the tag suffix
+ *
+ * This function will:
+ *  - Fetch all tags
+ *  - Filter for tags that match the existing tag suffix, if present
+ *  - Filter only tags that contain a semver version
+ */
+
 async function getPkgReleases(purl, config = {}) {
   const { fullname, qualifiers } = purl;
   const { registry, suffix } = qualifiers;
diff --git a/lib/datasource/github.js b/lib/datasource/github.js
index 9f9097e76592ba4830a457abaa4fa1d6cb43e16b..fc4c556659346745657d3c991c3444b068eab61d 100644
--- a/lib/datasource/github.js
+++ b/lib/datasource/github.js
@@ -37,6 +37,14 @@ function getCacheKey(repo, type) {
   return `${repo}:${type}`;
 }
 
+/*
+ * github.getDigest
+ *
+ * The `newValue` supplied here should be a valid tag for the docker image.
+ *
+ * This function will simply return the latest commit hash for the configured repository.
+ */
+
 async function getDigest(config) {
   let githubRepo = config.githubRepo || config.depNameShort;
   if (!githubRepo && config.purl) {
@@ -72,6 +80,18 @@ async function getDigest(config) {
   return digest;
 }
 
+/*
+ * github.getPkgReleases
+ *
+ * This function can be used to fetch releases with a customisable version scheme (e.g. semver) and with either tags or releases.
+ *
+ * This function will:
+ *  - Fetch all tags or releases (depending on configuration)
+ *  - Filter for only tags that meet the version scheme definition of a version
+ *  - Sanitize the versions if desired (e.g. strip out leading 'v')
+ *  - Return a dependency object containing repositoryUrl string and releases array
+ */
+
 async function getPkgReleases(purl, config) {
   const { versionScheme } = config || {};
   const { fullname: repo, qualifiers: options } = purl;
diff --git a/lib/datasource/go.js b/lib/datasource/go.js
index 9782da6db83093034d168e338bc08515cad9ae24..31bd674c35137e905196e4476f9e2df3f36f7ee6 100644
--- a/lib/datasource/go.js
+++ b/lib/datasource/go.js
@@ -55,6 +55,17 @@ async function getSourcePurl(name) {
   }
 }
 
+/*
+ * go.getPkgReleases
+ *
+ * This datasource resolves a go module URL into its source repository
+ *  and then fetch it if it is on GitHub.
+ *
+ * This function will:
+ *  - Determine the source URL for the module
+ *  - Call the respective getPkgReleases in github to retrieve the tags
+ */
+
 async function getPkgReleases(purl, config) {
   const { fullname: name } = purl;
   logger.trace(`go.getPkgReleases(${name})`);
@@ -66,6 +77,17 @@ async function getPkgReleases(purl, config) {
   return null;
 }
 
+/*
+ * go.getDigest
+ *
+ * This datasource resolves a go module URL into its source repository
+ *  and then fetches the digest it if it is on GitHub.
+ *
+ * This function will:
+ *  - Determine the source URL for the module
+ *  - Call the respective getDigest in github to retrieve the commit hash
+ */
+
 async function getDigest(config) {
   const githubPurl = await getSourcePurl(config.depName);
   if (githubPurl) {
diff --git a/lib/datasource/readme.md b/lib/datasource/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..90b986d5ad4c34572b4ece9d3ef9e2e3ade5a1d6
--- /dev/null
+++ b/lib/datasource/readme.md
@@ -0,0 +1,38 @@
+# Datasources
+
+Datasources are used in Renovate primarily to fetch released versions of packages.
+
+### getPkgReleases
+
+The minimum exported interface for a datasource is a function called `getPkgReleases` that takes a `purl` object as first input, and optionally `config` as the second argument.
+
+The `purl` object contains:
+
+- `fullname`: the package's full name including scope if present (e.g. `@foo/bar`)
+- `qualifiers`: optional addition arguments, may contain fields like `registry`
+
+In the simplest case, the datasource only needs to pay attention to `purl.fullname`.
+
+`getPkgReleases` should return an object containing:
+
+- `releases`: an array of strings of matched versions. This is the only mandatory field.
+- `deprecationMessage`: a string description of the package's deprecation notice, if applicable
+- `repositoryUrl`: a HTTP URL pointing to the source code (e.g. on GitHub)
+- `homepage`: a HTTP URL for the package's homepage. Ideally should be empty if the homepage and repositoryUrl are the same
+- `changelogUrl`: a URL pointing to the package's Changelog (could be a markdown file, for example). If not present then Renovate will search the `repositoryUrl` for a changelog file.
+- `tags`: an object mapping tag -> version, e.g. `tags: { latest: '3.0.0' }`. This is only used by the `followTags` function.
+
+### getDigest
+
+Datasources that support the concept of digests (e.g. docker digests and git commit hashes) also can export a `getDigest` function.
+
+The `getDigest` function has two inputs:
+
+- `config`: the Renovate config for the package being updated
+- `newValue`: the version or value to retrieve the digest for
+
+The `getDigest` function returns a string output representing the digest value. If none is found then a return value of `null` should be returned.
+
+### getPreset
+
+This function is supported by npm and github for retrieving a Renovate preset.
diff --git a/lib/datasource/terraform.js b/lib/datasource/terraform.js
index 3b35dffddfee93a5821886eb533ba0edacb5d4b8..b4293a66aa5244fdb95c9709ab72d845b877cd69 100644
--- a/lib/datasource/terraform.js
+++ b/lib/datasource/terraform.js
@@ -6,6 +6,14 @@ module.exports = {
   getPkgReleases,
 };
 
+/*
+ * terraform.getPkgReleases
+ *
+ * This function will fetch a package from the specified Terraform registry and return all semver versions.
+ *  - `repositoryUrl` is supported of "source" field is set
+ *  - `homepage` is set to the Terraform registry's page if it's on the official main registry
+ */
+
 async function getPkgReleases(purl) {
   const { fullname: dependency, qualifiers } = purl;
   const registry = qualifiers.registry || 'registry.terraform.io';