diff --git a/services/github/github-package-registry-version.service.js b/services/github/github-package-registry-version.service.js
new file mode 100644
index 0000000000000000000000000000000000000000..d8f095afe8282d1c8479fed0d38596574652190b
--- /dev/null
+++ b/services/github/github-package-registry-version.service.js
@@ -0,0 +1,185 @@
+'use strict'
+
+const gql = require('graphql-tag')
+const Joi = require('@hapi/joi')
+const { renderVersionBadge } = require('../version')
+const { GithubAuthV4Service } = require('./github-auth-service')
+const { documentation, transformErrors } = require('./github-helpers')
+const { NotFound } = require('..')
+
+// https://developer.github.com/v4/object/registrypackageversion/
+const packageVersion = Joi.object({
+  preRelease: Joi.bool().required(),
+  version: Joi.string().required(),
+})
+
+const latestVersionSchema = Joi.object({
+  data: Joi.object({
+    repository: Joi.object({
+      registryPackages: Joi.object({
+        nodes: Joi.array()
+          .items(
+            Joi.object({
+              latestVersion: packageVersion,
+            })
+          )
+          .min(0)
+          .required(),
+      }).required(),
+    }).required(),
+  }).required(),
+}).required()
+
+const versionSchema = Joi.object({
+  data: Joi.object({
+    repository: Joi.object({
+      registryPackages: Joi.object({
+        nodes: Joi.array()
+          .items(
+            Joi.object({
+              versions: Joi.object({
+                nodes: Joi.array()
+                  .items(packageVersion)
+                  .min(0)
+                  .required(),
+              }),
+            })
+          )
+          .min(0)
+          .required(),
+      }).required(),
+    }).required(),
+  }).required(),
+}).required()
+
+module.exports = class GithubPackageRegistryVersion extends GithubAuthV4Service {
+  static get category() {
+    return 'version'
+  }
+
+  static get route() {
+    return {
+      base: 'github/packages',
+      pattern: ':type(v|vpre)/:user/:repo/:packageName',
+    }
+  }
+
+  static get examples() {
+    return [
+      {
+        title: 'GitHub Package Registry Version (with prereleases)',
+        pattern: 'vpre/:user/:repo/:packageName',
+        namedParams: {
+          user: 'github',
+          repo: 'semantic',
+          packageName: 'semantic',
+        },
+        staticPreview: renderVersionBadge({ version: '0.8.0.0' }),
+        documentation,
+      },
+      {
+        title: 'GitHub Package Registry Version',
+        pattern: 'v/:user/:repo/:packageName',
+        namedParams: {
+          user: 'github',
+          repo: 'auto-complete-element',
+          packageName: 'auto-complete-element',
+        },
+        staticPreview: renderVersionBadge({ version: '0.8.0.0' }),
+        documentation,
+      },
+    ]
+  }
+
+  static get defaultBadgeData() {
+    return { label: 'version' }
+  }
+
+  async fetch({ user, repo, packageName, includePrereleases }) {
+    if (includePrereleases) {
+      return await this._requestGraphql({
+        query: gql`
+          query($user: String!, $repo: String!, $packageName: String!) {
+            repository(owner: $user, name: $repo) {
+              registryPackages(name: $packageName, first: 1) {
+                nodes {
+                  latestVersion {
+                    preRelease
+                    version
+                  }
+                }
+              }
+            }
+          }
+        `,
+        variables: { user, repo, packageName },
+        schema: latestVersionSchema,
+        transformErrors,
+      })
+    } else {
+      return await this._requestGraphql({
+        query: gql`
+          query($user: String!, $repo: String!, $packageName: String!) {
+            repository(owner: $user, name: $repo) {
+              registryPackages(name: $packageName, first: 1) {
+                nodes {
+                  versions(first: 1) {
+                    nodes {
+                      preRelease
+                      version
+                    }
+                  }
+                }
+              }
+            }
+          }
+        `,
+        variables: { user, repo, packageName },
+        schema: versionSchema,
+        transformErrors,
+      })
+    }
+  }
+
+  transform({ json, includePrereleases }) {
+    const {
+      data: {
+        repository: {
+          registryPackages: {
+            nodes: [ghPackage],
+          },
+        },
+      },
+    } = json
+
+    if (!ghPackage) {
+      throw new NotFound({ prettyMessage: 'package not found' })
+    }
+
+    if (includePrereleases) {
+      const {
+        latestVersion: { version },
+      } = ghPackage
+      return { version }
+    } else {
+      const {
+        versions: {
+          nodes: [{ version }],
+        },
+      } = ghPackage
+      return { version }
+    }
+  }
+
+  async handle({ type, user, repo, packageName }) {
+    const includePrereleases = type === 'vpre'
+    const json = await this.fetch({
+      user,
+      repo,
+      packageName,
+      includePrereleases,
+    })
+    const { version } = this.transform({ json, includePrereleases })
+    return renderVersionBadge({ version })
+  }
+}
diff --git a/services/github/github-package-registry-version.tester.js b/services/github/github-package-registry-version.tester.js
new file mode 100644
index 0000000000000000000000000000000000000000..0a855766561f92f3854b05cad22da9cfce6d4c12
--- /dev/null
+++ b/services/github/github-package-registry-version.tester.js
@@ -0,0 +1,40 @@
+'use strict'
+
+const Joi = require('@hapi/joi')
+const {
+  isVPlusDottedVersionNClausesWithOptionalSuffix,
+} = require('../test-validators')
+const t = (module.exports = require('../tester').createServiceTester())
+
+const isPackageVersion = Joi.alternatives().try(
+  isVPlusDottedVersionNClausesWithOptionalSuffix,
+  Joi.string().required()
+)
+
+t.create('Package Registry version (non-existent repository)')
+  .get('/v/badges/not-a-real-repo/super-fake-package.json')
+  .expectBadge({
+    label: 'version',
+    message: 'repo not found',
+  })
+
+t.create('Package Registry version (non-existent package)')
+  .get('/v/badges/shields/super-fake-package.json')
+  .expectBadge({
+    label: 'version',
+    message: 'package not found',
+  })
+
+t.create('Package Registry version (pre-release)')
+  .get('/vpre/UiPath/angular-components/angular.json')
+  .expectBadge({
+    label: 'version',
+    message: isPackageVersion,
+  })
+
+t.create('Package Registry version (release)')
+  .get('/v/github/semantic/semantic.json')
+  .expectBadge({
+    label: 'version',
+    message: isPackageVersion,
+  })