diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index 7a9c29fbd4dc5743bbad6953b71fc593c7ccb9f8..67551f14fc27c2f4b391a3232ea51868bd71f25d 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -526,6 +526,10 @@ Example for configuring `docker` auth:
 }
 ```
 
+## html
+
+Supports subresource integrity (SRI) hashes.
+
 ### baseUrl
 
 Use this instead of `domainName` or `hostName` if you need a rule to apply to a specific path on a host. For example, `"baseUrl": "https://api.github.com"` is equivalent to `"hostName": "api.github.com"` but `"baseUrl": "https://api.github.com/google/"` is not.
diff --git a/lib/datasource/cdnjs/index.ts b/lib/datasource/cdnjs/index.ts
index 7cdb260f9247830777b568b25ff1dda8ed4ce66c..5ce0a667ccc77625b13b418d5a4802d33751fe48 100644
--- a/lib/datasource/cdnjs/index.ts
+++ b/lib/datasource/cdnjs/index.ts
@@ -3,15 +3,16 @@ import got from '../../util/got';
 import { DatasourceError, ReleaseResult, PkgReleaseConfig } from '../common';
 import { DATASOURCE_CDNJS } from '../../constants/data-binary-source';
 
-interface CdnjsAsset {
+export interface CdnjsAsset {
   version: string;
   files: string[];
+  sri?: Record<string, string>;
 }
 
 const cacheNamespace = `datasource-${DATASOURCE_CDNJS}`;
 const cacheMinutes = 60;
 
-interface CdnjsResponse {
+export interface CdnjsResponse {
   homepage?: string;
   repository?: {
     type: 'git' | unknown;
@@ -20,6 +21,10 @@ interface CdnjsResponse {
   assets?: CdnjsAsset[];
 }
 
+export function depUrl(depName: string): string {
+  return `https://api.cdnjs.com/libraries/${depName}?fields=homepage,repository,assets`;
+}
+
 export async function getPkgReleases({
   lookupName,
 }: Partial<PkgReleaseConfig>): Promise<ReleaseResult | null> {
@@ -40,7 +45,7 @@ export async function getPkgReleases({
   // istanbul ignore if
   if (cachedResult) return cachedResult;
 
-  const url = `https://api.cdnjs.com/libraries/${depName}?fields=homepage,repository,assets`;
+  const url = depUrl(depName);
 
   try {
     const res = await got(url, { json: true });
diff --git a/lib/manager/cdnurl/extract.ts b/lib/manager/cdnurl/extract.ts
index 10380ba0745622cbd057771a9fbf8f50cefe39e5..070583aa088bcc060ee068a6c1d5065824347242 100644
--- a/lib/manager/cdnurl/extract.ts
+++ b/lib/manager/cdnurl/extract.ts
@@ -1,12 +1,13 @@
 import { PackageFile, PackageDependency } from '../common';
 import { DATASOURCE_CDNJS } from '../../constants/data-binary-source';
 
+export const cloudflareUrlRegex = /\/\/cdnjs\.cloudflare\.com\/ajax\/libs\/(?<depName>[^/]+?)\/(?<currentValue>[^/]+?)\/(?<asset>[-_.a-zA-Z0-9]+)/;
+
 export function extractPackageFile(content: string): PackageFile {
   const deps: PackageDependency[] = [];
 
-  const regex = /\/\/cdnjs\.cloudflare\.com\/ajax\/libs\/(?<depName>[^/]+?)\/(?<currentValue>[^/]+?)\/(?<asset>[-_.a-zA-Z0-9]+)/;
   let rest = content;
-  let match = regex.exec(rest);
+  let match = cloudflareUrlRegex.exec(rest);
   let offset = 0;
   while (match) {
     const [wholeSubstr] = match;
@@ -17,7 +18,7 @@ export function extractPackageFile(content: string): PackageFile {
 
     offset += match.index + wholeSubstr.length;
     rest = content.slice(offset);
-    match = regex.exec(rest);
+    match = cloudflareUrlRegex.exec(rest);
 
     deps.push({
       datasource: DATASOURCE_CDNJS,
diff --git a/lib/manager/html/__fixtures__/axios.json b/lib/manager/html/__fixtures__/axios.json
new file mode 100644
index 0000000000000000000000000000000000000000..755f8710c9a1f349b685249bf30a279ee10e9fa5
--- /dev/null
+++ b/lib/manager/html/__fixtures__/axios.json
@@ -0,0 +1,735 @@
+{
+  "homepage": null,
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/mzabriskie/axios.git"
+  },
+  "assets": [
+    {
+      "version": "0.19.2",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-bd8XIKzrtyJ1O5Sh3Xp3GiuMIzWC42ZekvrMMD4GxRg=",
+        "axios.min.js": "sha256-T/f7Sju1ZfNNfBh7skWn0idlCBcI3RwdLSS4/I7NQKQ="
+      }
+    },
+    {
+      "version": "0.19.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-J6UlS3kpnhiSiNQ9lGoV9Q94ZpIPff3UZcR0dDwIT6g=",
+        "axios.min.js": "sha256-Hhwv1ElzvrH6ZuiIDWEO6xBYW3lmFYrapwcjgXhpL6g="
+      }
+    },
+    {
+      "version": "0.19.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-XmdRbTre/3RulhYk/cOBUMpYlaAp2Rpo/s556u0OIKk=",
+        "axios.min.js": "sha256-S1J4GVHHDMiirir9qsXWc8ZWw74PHHafpsHp5PXtjTs="
+      }
+    },
+    {
+      "version": "0.19.0-beta.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-ZqHpIRQ/P2PzIkK170Ic9ShWNHUMEXSriS6hJqHgPCk=",
+        "axios.min.js": "sha256-bSwKRQoEtdFJL3fX5RL+avJulcL+rFloJfRecbn/pNY="
+      }
+    },
+    {
+      "version": "0.18.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-31i7lDZ6fiW6ZFO5j7kMPG9dmM8zPbs8ZzdeffTeKPg=",
+        "axios.min.js": "sha256-S1ZKMF2XMLympjZScWBS5TzFKKKRQ+UQYsbw6ioZY/s="
+      }
+    },
+    {
+      "version": "0.18.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-lrZTgsdM1iVdRigETFOU8u8/BmLX1ysQ8bzrULbuVFU=",
+        "axios.min.js": "sha256-mpnrJ5DpEZZkwkE1ZgkEQQJW/46CSEh/STrZKOB/qoM="
+      }
+    },
+    {
+      "version": "0.17.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-hz0JuA8OZxhBijQKyIdMoVRE9lnBt+0phoPt4PiAnQc=",
+        "axios.min.js": "sha256-A83FHt22LbSOPYN9dGs74h/J0jqc3TZapHUplf2uupI="
+      }
+    },
+    {
+      "version": "0.17.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-dA/IRPLskb4wlHpyPNPPI0GNBX3lFbvLYiLy5laCewY=",
+        "axios.min.js": "sha256-ReCG8xthuE96rBkv5Cr/V+Wg42Gst+HCf0kNQufB9as="
+      }
+    },
+    {
+      "version": "0.16.2",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-JXU9bC6uJttvR5dnFkXWImMeNfVl0MwHM8OdBtdGtJs=",
+        "axios.min.js": "sha256-aXHOBRCjmgqoEhY6VBWs3Bc+E3447Iuywezt+nkgeZk="
+      }
+    },
+    {
+      "version": "0.16.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-ypSziIupDDkOvNExCPbqq+U4ufKgLB9B0P7oFQPeXoc=",
+        "axios.min.js": "sha256-ayEUoFCu1J9KJCN9TR9De3XKEMb8hiPq4jwFWMU6fiE="
+      }
+    },
+    {
+      "version": "0.16.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-T+17oIAlzSvCwsm50V4ByFrFWtmGIlE3rJdob1AbARs=",
+        "axios.min.js": "sha256-ObAJM4i2OoNkYK9RdcsPGm9+dsHUOAY1r8PYR7XoEVw="
+      }
+    },
+    {
+      "version": "0.15.3",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-CoA7Q6Hwn87/erPTxiI0k/susrtAfkh8i84ZdSWAzAM=",
+        "axios.min.js": "sha256-xEofWHiBewJOBXBSH5JHWuwCYpBKOQ8KSGSVLbEVYyo="
+      }
+    },
+    {
+      "version": "0.15.2",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-iWv6d2qgmadTj3wBUhvWE0bHAca0Dqh9r4FJ3A7fnmQ=",
+        "axios.min.js": "sha256-HGV3LcrrHFFi+8L71R2WxfVzKUwvYSorfbhpBnBSdeI="
+      }
+    },
+    {
+      "version": "0.15.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-K4sDedAxh0HyQN871EEZyOSUysqEW2IHYti4ZqMSSNA=",
+        "axios.min.js": "sha256-lls3OSV8iEyV3Dh3Q3OjYJpT0rxp/GD/j+j4PKyrezc="
+      }
+    },
+    {
+      "version": "0.15.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-Rt/oYNvoXxDtdMzNkafEhu4c8VQXQBZ3S7X35p+XQP8=",
+        "axios.min.js": "sha256-8Jg6SAzzes9UsrOJAOi5bB9YWSe6ymy9CRcTGaOXCic="
+      }
+    },
+    {
+      "version": "0.14.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-Vm0pP8VEIOlB2rjV0g1w9KRwMsxp22W1poig8qTunEk=",
+        "axios.min.js": "sha256-SJPIVv+jVR0706q0zyyv+nvh3S+uDLtE88MX0paHRTI="
+      }
+    },
+    {
+      "version": "0.13.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-tCjUyThC4mGL5FnYcRim6jOIRL7dHT+C2N8LbpYuCGk=",
+        "axios.min.js": "sha256-DgCivPJ94y8Rey1b9I2xjEZI6anDVb1tPfKQ/7Fc6Y0="
+      }
+    },
+    {
+      "version": "0.13.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-Nc1U012U+5QcuH4YWwzOOYBjNDQ5LwVG4m6PWUeBRnM=",
+        "axios.min.js": "sha256-G+DsWAnEuvDYcg7/r++UTlY6XTLa9PF3YqWYtpKSHJI="
+      }
+    },
+    {
+      "version": "0.12.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-PMzk0phP+2zPylqWAu5emj2zZK5vRpcHbNum+36fIz0=",
+        "axios.min.js": "sha256-csxVtQ9PWNN5RZXL1dB8In2Lcl3Y4RHpeIjOcmsL5jo="
+      }
+    },
+    {
+      "version": "0.11.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-dmt8/T+OHZGsyiFyegLBcu64wcwYBmkLWYXZSZjxgyg=",
+        "axios.min.js": "sha256-WJav8RK+T2ICcOk8vtuOqG1Ou6juy3MKd7OLQBXHIIw="
+      }
+    },
+    {
+      "version": "0.11.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-QfDStqy65wvLD4DwLkZA//VnPvrw984nkkgEtNbXgkg=",
+        "axios.min.js": "sha256-VSuBJZeVAKgx0qYnY9I3FJzl2qWdnZNtpNR4oBs1RlQ="
+      }
+    },
+    {
+      "version": "0.10.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-Yald8dk0loah6tTZzkndi//0F7M1aEBu3HZkTXH+v48=",
+        "axios.min.js": "sha256-kaXZv9ANyLjWnN68PmNky9uze4/aWMkwTrvpBxFtwlc="
+      }
+    },
+    {
+      "version": "0.9.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-83oF3gfsUBp0ghAHDTN0RWODjqwm0YXSeqncGsditTg=",
+        "axios.min.js": "sha256-h7EClez70bXfUgOmH6/kkHxD1R00CnjhKwqtrhTP5aw="
+      }
+    },
+    {
+      "version": "0.9.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-efCF1BCwDzHU8Uq+PRXluTIShRQoTVXbq0ZgSjVOrE0=",
+        "axios.min.js": "sha256-Ps3e+n52Zpzcsk0lAU9yy/NAt5E70iySkC9dCUVmfjA="
+      }
+    },
+    {
+      "version": "0.8.1",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-7WFK995Wu+4FASmH9mNWaZM0wDVREo2QkMxxRSnq41c=",
+        "axios.min.js": "sha256-UyoNsJudoxoA30F8HgsoLYr7I7lp3aRC/+MozU9bW5E="
+      }
+    },
+    {
+      "version": "0.8.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-OAjlZ/feZOd2wVVnF6F0pEHkW8y2GNDGJLMgurXHc2c=",
+        "axios.min.js": "sha256-eR5iyxOlAv10LOIaAFAeJm0zCyzW9B4vk39uB/OTen8="
+      }
+    },
+    {
+      "version": "0.7.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-saQTyR4zi5l7TVRUxptHQMqBGOx7fD5SKKfat55ruZ4=",
+        "axios.min.js": "sha256-oNArrP+cvywx4l1Pq1aF3RsFxNiQ3tQw85I+5ezYRhY="
+      }
+    },
+    {
+      "version": "0.6.0",
+      "files": [
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.js": "sha256-LOe2iPuwjadzSFU/6zmcriOw6IjjRXmw4niNoyBGeLs=",
+        "axios.min.js": "sha256-4CH9pIWieQh2Ec9P0asKveu6bKRWvyTKsbGmZBN2gfA="
+      }
+    },
+    {
+      "version": "0.5.4",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-sOaBEQwUg29tJQD8dbLu/KILpD4DUL8VcYaU2uINxOc=",
+        "axios.amd.min.js": "sha256-dQDGJXqS4BPeiJOBImGsVCDANDbfaDEeYV3HmM3tX80=",
+        "axios.amd.standalone.js": "sha256-hkH91dJSTBFMDypqAMAn98yglc6nAsfqqqcb0DoOGjA=",
+        "axios.amd.standalone.min.js": "sha256-vHnhp3Z+YK5/bEvHdv0nmJ5pfPxXgukjTpZDhVrGif8=",
+        "axios.js": "sha256-GUtcBGSxIowk1OaIuj7BJYoYFjGb05BOtz18I8a83eE=",
+        "axios.min.js": "sha256-S88N3SCdTfPsj0EbuTxLTmcXF/Nyk4CEMyHQFHIvsZk=",
+        "axios.standalone.js": "sha256-fRhO4mk5kMBw9wWqJbPO41u+OAIkMfA4GysGMIBc+nw=",
+        "axios.standalone.min.js": "sha256-7a3wJ0QTMnoOgadW7sIVGi0niQwd0NpcmlC4cUdPIOU="
+      }
+    },
+    {
+      "version": "0.5.3",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-sCpgdK85mLhxJQ6qyRJEwVZmc7oF5LxanvCOZq8aVUw=",
+        "axios.amd.min.js": "sha256-7zVb1BvJAF1usTlEbPbNvu2zC4rBgwVfCl98f1Dim6E=",
+        "axios.amd.standalone.js": "sha256-5Tng3+o4N/yXEwcyk+97YFpIZW2aMqrJ+hh2SUTAQUo=",
+        "axios.amd.standalone.min.js": "sha256-vfdXazOpXgPmMPodjecf/MddNCY8x25JSgu9scwvzcM=",
+        "axios.js": "sha256-Ua1CfWsJlrjxIAmqLa5wbGdDc4UctQjBjkLPI1CwI+I=",
+        "axios.min.js": "sha256-tlCdmGzflQbn0gzGieVQObRUYo3Mti6Tou6xtMSGDVE=",
+        "axios.standalone.js": "sha256-i+ZQ0DfACTXPVzLCRZ5dAlpPR5Xvs7CpHl8bzI2ctxk=",
+        "axios.standalone.min.js": "sha256-GUg8pDD1NPN8kbGdMKgvu1ygRGY7lDwtI6gaKYgCXkw="
+      }
+    },
+    {
+      "version": "0.5.2",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-WKQvVN5DUioGsmOgFUTrfc3lCh9JRjvbsMif509nuk8=",
+        "axios.amd.min.js": "sha256-JRWYXs4+OofAsf3WhWuZY01hDEU+lSvzt/PoR9VogLc=",
+        "axios.amd.standalone.js": "sha256-+R0Cbj6oag/Fzl12fIc9aNMs+EjeEcDevODga+oQeo8=",
+        "axios.amd.standalone.min.js": "sha256-mqGU7g/G0q/QfUHZFidO6tgeFpuGbQgVBLazIu9nXNM=",
+        "axios.js": "sha256-MYs6yGKRVKAYdsROXwLLfVhpZ8lBzoIx6SjfJX3FN+Y=",
+        "axios.min.js": "sha256-zKXcsOre8tgitwkcgGRc1sHMgvEw0pFwtYcop/o2S/8=",
+        "axios.standalone.js": "sha256-RsB2QYN9V4ofc98KlqOIQxBEknYqRVMnbEWbjoN8phw=",
+        "axios.standalone.min.js": "sha256-ZP1TKRktCKF7TlW/QtxQVWhuE08DNElhowAz3/Hd6zk="
+      }
+    },
+    {
+      "version": "0.5.1",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-AdoAC/wOuoojkniCeWE3Ya4Li5ZqLZy+MFZDFaOo35w=",
+        "axios.amd.min.js": "sha256-veB8njUVlmL4vx4Xggx1xPR9+vX0bAlccRMlQSKj8yI=",
+        "axios.amd.standalone.js": "sha256-QPhnt2+R6K+WoMSnuc/+oH9G0bfmMX4sajBhTBa2oSU=",
+        "axios.amd.standalone.min.js": "sha256-m2P300LwJ56H1GiuyqMMXSV1Gv1XZptvnI5xXzxh/v8=",
+        "axios.js": "sha256-wvRDymtx/Y0GbT2GKg8FJL5bCNf/uhRF3DbPxFPFDac=",
+        "axios.min.js": "sha256-z5tToupgSYDS4I9fJqXS3HGFRDzqSJ1j+DlffypzPZc=",
+        "axios.standalone.js": "sha256-5H+f9ePwTUT/COh5rUwZWPrJCFC+378YfRDOHqBJhyM=",
+        "axios.standalone.min.js": "sha256-zVZYO5XLlV15BBD74wC3ug7lqcv6jwxrbl5TBkG8aaw="
+      }
+    },
+    {
+      "version": "0.5.0",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-Jo4eK49MGwCgwsSLYYpLrQkfKL5y+62VPTa5LGFyNCI=",
+        "axios.amd.min.js": "sha256-RbPdz8juY0+5CgjiusZLpRbsHbDwucz6MdWOLE2QDQw=",
+        "axios.amd.standalone.js": "sha256-UhbAjgU2ulf0m7s377RFj1h2yMTL1ddt8FQ/+Wfxmtw=",
+        "axios.amd.standalone.min.js": "sha256-uua9134hcuhlIbT5X3aOZSIDIxECjWVCmdI5ERpULhc=",
+        "axios.js": "sha256-fcaYzMAfYg3yiP/LcZgMvrLf/+Tbmeak2pgLD5vuogU=",
+        "axios.min.js": "sha256-Vlr5MzIHMo3xs69Xil4eSmFoQGqCpFm8AtdCBjjDQds=",
+        "axios.standalone.js": "sha256-tGcO6GbEvKbSv0J/KtNrPK9MBpgJCr36u0EmBxAZNNw=",
+        "axios.standalone.min.js": "sha256-N7MjtQqiO9QdZxcwzXgndDCQlpegqWN62n1bZpZiPcg="
+      }
+    },
+    {
+      "version": "0.4.2",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-XGL7P8Qo2Vs6m/MjCag5JCoNjlt3+kUIhKKeeyC9C1U=",
+        "axios.amd.min.js": "sha256-hVzh6bTdyXXIey+ZUNMFaVzz8PG0MzUaSUZs14Aop9I=",
+        "axios.amd.standalone.js": "sha256-p77AbisCqmu2bTY+RqyaIdLitqUcDhU13l4f5H1MA8I=",
+        "axios.amd.standalone.min.js": "sha256-ue+UbzUfyIsOk/csooZxid4tiEIdiJsAKgaqgYF9J+8=",
+        "axios.js": "sha256-KCUXSHgZqPmReBtsLPwUDm8OgPaupK7bPAllTyXOFkQ=",
+        "axios.min.js": "sha256-G5meWybNofoQcianhTk+YD1Fv3kuz56Ggp+uaW5wGlM=",
+        "axios.standalone.js": "sha256-6k2R8GRelLqOL56m4nH6wsgVEpKA3RHpX6nC4YDGvxA=",
+        "axios.standalone.min.js": "sha256-LsR4anEOthPDJ8IgugrhUyRWOw4j8u878nHIkLDNISI="
+      }
+    },
+    {
+      "version": "0.4.1",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-VrHZHqx3eQfjjb2U7X2RSrFgXp4Jt5ytghfpWyAKSbk=",
+        "axios.amd.min.js": "sha256-Q7o/soA/Dg284+MhOPK8oAUGmCkFKXp2G/97EOG7YG8=",
+        "axios.amd.standalone.js": "sha256-pcNWqLcQAN7V4kcBIGTFLJTq5KkhrU0E/q4qqjb32s0=",
+        "axios.amd.standalone.min.js": "sha256-o5DzCzTel3TPoCbyqV770yZCoIy6Wq6iozOhC/BFt/0=",
+        "axios.js": "sha256-d+ozccBT3SOii8qnnMplRF+lLpEAX+cbCnpEZ6+By70=",
+        "axios.min.js": "sha256-Wz0es0IFZx02G899aJG20WOIa2JwKlDKZjz502J0Gk4=",
+        "axios.standalone.js": "sha256-FbhL3JuEx/QancTaUF3CfAvAm+sGiTeaKxmBmFpXJwM=",
+        "axios.standalone.min.js": "sha256-W9HY7fDSlUty5hr5hNdB7s3bMm/+1sdh7sOFb9QfuHU="
+      }
+    },
+    {
+      "version": "0.4.0",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.amd.standalone.js",
+        "axios.amd.standalone.map",
+        "axios.amd.standalone.min.js",
+        "axios.amd.standalone.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map",
+        "axios.standalone.js",
+        "axios.standalone.map",
+        "axios.standalone.min.js",
+        "axios.standalone.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-VrHZHqx3eQfjjb2U7X2RSrFgXp4Jt5ytghfpWyAKSbk=",
+        "axios.amd.min.js": "sha256-uFv/CHFO8JXCt9ItCcTWpLf3D2eF0OoyvzRvJV+3LwA=",
+        "axios.amd.standalone.js": "sha256-pcNWqLcQAN7V4kcBIGTFLJTq5KkhrU0E/q4qqjb32s0=",
+        "axios.amd.standalone.min.js": "sha256-492XMFTsHTHz9GLbPrGDd3U0eSAjKfzcSxuzypcBG7o=",
+        "axios.js": "sha256-d+ozccBT3SOii8qnnMplRF+lLpEAX+cbCnpEZ6+By70=",
+        "axios.min.js": "sha256-TrKSJDNI8PpMqPX1n7Ti0ixZUcUwOiMKlTwjVP84kiA=",
+        "axios.standalone.js": "sha256-FbhL3JuEx/QancTaUF3CfAvAm+sGiTeaKxmBmFpXJwM=",
+        "axios.standalone.min.js": "sha256-kLNSBcupJKbLvzfSiOsuHEIo5Dzy9FIr0laugQE6kkM="
+      }
+    },
+    {
+      "version": "0.3.1",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-ytZfb6ETyqVVhnLdhby3+rWTt6GK7uuL/3IiSlD5Ros=",
+        "axios.amd.min.js": "sha256-MmF2qd+Svi22/N6+KIsIjKL4DSLLrbU/Rr+NKxznG9Q=",
+        "axios.js": "sha256-Cu3lPIJNitm3o8Lfdjk1kbD4mQdSr8WcQp9doWFy6Pc=",
+        "axios.min.js": "sha256-YkZWt1pzs6AXP2AI1lQgw7uVmUN6mxOoCpgUs3zsQ3U="
+      }
+    },
+    {
+      "version": "0.3.0",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-istZoqHbUelguVMqKUSc3Sfxs7HNtmexHr77HkUys4M=",
+        "axios.amd.min.js": "sha256-pouRkAFfxMDOgelC1R5ZTdm9Y1CtuqE5J/ukX2OA/so=",
+        "axios.js": "sha256-VgCS0XhnH+fAKqw4QIR3wDrq6CFCOjLtTMdkKnA7/DU=",
+        "axios.min.js": "sha256-B74j9ffhoGXojFL96VJYSuFiRVI+02ZEOlb4ZSi6Qt8="
+      }
+    },
+    {
+      "version": "0.2.2",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-sZT5WJ8xk8oehL8q93lalAVo3u4bAG9jR46gg8rKGzE=",
+        "axios.amd.min.js": "sha256-0Ex63KsanSd/AwxaYdJ08KwTq+CPlIdBJeYI2ZJug6M=",
+        "axios.js": "sha256-Fwba+Y4iG/IlfTBUVlie/SImG/46hgsoWP3lOdVTATs=",
+        "axios.min.js": "sha256-+W/p3P+2uahykgCnBj5OoumtqohkAijkWQCAuOxTFgk="
+      }
+    },
+    {
+      "version": "0.2.1",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-sZT5WJ8xk8oehL8q93lalAVo3u4bAG9jR46gg8rKGzE=",
+        "axios.amd.min.js": "sha256-IeZM3agJwVsjozOE7kbQd1YobMk4cgqMqFvfuNUDoLo=",
+        "axios.js": "sha256-Fwba+Y4iG/IlfTBUVlie/SImG/46hgsoWP3lOdVTATs=",
+        "axios.min.js": "sha256-XqCScc27q1doCKzdXUIZLdPQLg6smR8eHk6OMd8eg9k="
+      }
+    },
+    {
+      "version": "0.2.0",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-OGdJK8h4ZiJGwADF+EVMb08ikc+QCQB3wqAx2GFqPM0=",
+        "axios.amd.min.js": "sha256-3fHLlzw/h4S/Pm5dNl5+2qtiAgSFVJY3n+T7ut//3t8=",
+        "axios.js": "sha256-kukqmgfj39Y+Km2LJJspgNqyZCMaHiz4jurzFi5IGzA=",
+        "axios.min.js": "sha256-LAwrvWRsNpgH3aC2RQ2oM0v/pry4S6LDolujdBmVzpw="
+      }
+    },
+    {
+      "version": "0.1.0",
+      "files": [
+        "axios.amd.js",
+        "axios.amd.map",
+        "axios.amd.min.js",
+        "axios.amd.min.map",
+        "axios.js",
+        "axios.map",
+        "axios.min.js",
+        "axios.min.map"
+      ],
+      "sri": {
+        "axios.amd.js": "sha256-wD7lK/ShXIHR99KWXprW8JrMZQ2W58k0bbn5yWfNxLw=",
+        "axios.amd.min.js": "sha256-J9ZMsmGjh9igOEU5hudw/npiimIeOLiY50clicYczLE=",
+        "axios.js": "sha256-/c9uhxbedN+Vpm+NIgwtkDoA1bOdUTk9/Ql8Rm+Phv4=",
+        "axios.min.js": "sha256-h8uKNfZwiaVkmQYDB9j8o599E5U4C1XaKzBJclapLO8="
+      }
+    }
+  ]
+}
diff --git a/lib/manager/html/__fixtures__/sample.html b/lib/manager/html/__fixtures__/sample.html
new file mode 100644
index 0000000000000000000000000000000000000000..874b53417990ab09ae214832a3f3ecaf3e541a3c
--- /dev/null
+++ b/lib/manager/html/__fixtures__/sample.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+
+  <head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- Required dependencies -->
+    <script type="text/javascript"
+            src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.1/prop-types.min.js"></script>
+    <script type="text/javascript"
+            src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.2/umd/react.production.min.js"></script>
+    <script type="text/javascript"
+            src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.2/umd/react-dom.production.min.js"></script>
+    <script type="application/javascript" src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
+    <script type="text/babel" data-presets="es2017, stage-3"
+            data-plugins="syntax-async-functions,transform-class-properties,transform-es2015-modules-umd, transform-async-to-generator"></script>
+    <!-- Optional dependencies -->
+    <script type="text/javascript"
+            src="https://cdnjs.cloudflare.com/ajax/libs/react-transition-group/2.2.1/react-transition-group.min.js"></script>
+    <script type="text/javascript"
+            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
+    <script type="text/javascript"
+            src="https://cdnjs.cloudflare.com/ajax/libs/react-popper/0.10.4/umd/react-popper.min.js"></script>
+    <!-- Reactstrap -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/7.1.0/reactstrap.min.js"></script>
+    <script src=" https://cdnjs.cloudflare.com/ajax/libs/react-router/4.3.1/react-router.min.js"></script>
+
+
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-markdown/4.0.6/react-markdown.js"></script>
+    <script src="https://unpkg.com/react-router-dom@4.3.1/umd/react-router-dom.min.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"
+            integrity="sha256-mpnrJ5DpEZZkwkE1ZgkEQQJW/46CSEh/STrZKOB/qoM=" crossorigin="anonymous"></script>
+
+    <!-- Lastly, include your app's bundle -->
+    <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
+    <link type="text/css" rel="stylesheet" href="css/custom.css"/>
+
+
+  </head>
+
+  <body>
+
+    <div id="root"></div>
+
+
+    <script type="text/babel" src="js/main.jsx"></script>
+
+  </body>
+
+</html>
diff --git a/lib/manager/html/__snapshots__/extract.spec.ts.snap b/lib/manager/html/__snapshots__/extract.spec.ts.snap
new file mode 100644
index 0000000000000000000000000000000000000000..23d023c5a45ee20917de8bb56787673972665247
--- /dev/null
+++ b/lib/manager/html/__snapshots__/extract.spec.ts.snap
@@ -0,0 +1,108 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`manager/html/extract extractPackageFile 1`] = `
+Object {
+  "deps": Array [
+    Object {
+      "currentValue": "15.6.1",
+      "datasource": "cdnjs",
+      "depName": "prop-types",
+      "lookupName": "prop-types/prop-types.min.js",
+      "managerData": Object {
+        "tagLength": 124,
+        "tagPosition": 201,
+      },
+    },
+    Object {
+      "currentValue": "16.3.2",
+      "datasource": "cdnjs",
+      "depName": "react",
+      "lookupName": "react/umd",
+      "managerData": Object {
+        "tagLength": 129,
+        "tagPosition": 339,
+      },
+    },
+    Object {
+      "currentValue": "16.3.2",
+      "datasource": "cdnjs",
+      "depName": "react-dom",
+      "lookupName": "react-dom/umd",
+      "managerData": Object {
+        "tagLength": 137,
+        "tagPosition": 482,
+      },
+    },
+    Object {
+      "currentValue": "2.2.1",
+      "datasource": "cdnjs",
+      "depName": "react-transition-group",
+      "lookupName": "react-transition-group/react-transition-group.min.js",
+      "managerData": Object {
+        "tagLength": 147,
+        "tagPosition": 984,
+      },
+    },
+    Object {
+      "currentValue": "1.14.3",
+      "datasource": "cdnjs",
+      "depName": "popper.js",
+      "lookupName": "popper.js/umd",
+      "managerData": Object {
+        "tagLength": 123,
+        "tagPosition": 1145,
+      },
+    },
+    Object {
+      "currentValue": "0.10.4",
+      "datasource": "cdnjs",
+      "depName": "react-popper",
+      "lookupName": "react-popper/umd",
+      "managerData": Object {
+        "tagLength": 132,
+        "tagPosition": 1282,
+      },
+    },
+    Object {
+      "currentValue": "7.1.0",
+      "datasource": "cdnjs",
+      "depName": "reactstrap",
+      "lookupName": "reactstrap/reactstrap.min.js",
+      "managerData": Object {
+        "tagLength": 88,
+        "tagPosition": 1452,
+      },
+    },
+    Object {
+      "currentValue": "4.3.1",
+      "datasource": "cdnjs",
+      "depName": "react-router",
+      "lookupName": "react-router/react-router.min.js",
+      "managerData": Object {
+        "tagLength": 93,
+        "tagPosition": 1554,
+      },
+    },
+    Object {
+      "currentValue": "4.0.6",
+      "datasource": "cdnjs",
+      "depName": "react-markdown",
+      "lookupName": "react-markdown/react-markdown.js",
+      "managerData": Object {
+        "tagLength": 92,
+        "tagPosition": 1663,
+      },
+    },
+    Object {
+      "currentValue": "0.18.0",
+      "datasource": "cdnjs",
+      "depName": "axios",
+      "lookupName": "axios/axios.min.js",
+      "managerData": Object {
+        "tagLength": 179,
+        "tagPosition": 1866,
+      },
+    },
+  ],
+}
+`;
diff --git a/lib/manager/html/extract.spec.ts b/lib/manager/html/extract.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c7ddaeb96c95bfcbe2aa6ae03973592877ba9ba3
--- /dev/null
+++ b/lib/manager/html/extract.spec.ts
@@ -0,0 +1,14 @@
+import { readFileSync } from 'fs';
+import { resolve } from 'path';
+import { extractPackageFile } from '.';
+
+const input = readFileSync(
+  resolve(__dirname, `./__fixtures__/sample.html`),
+  'utf8'
+);
+
+describe('manager/html/extract', () => {
+  it('extractPackageFile', () => {
+    expect(extractPackageFile(input)).toMatchSnapshot();
+  });
+});
diff --git a/lib/manager/html/extract.ts b/lib/manager/html/extract.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6e179c3102c44a42bd6becbd595c8d7f764f5d05
--- /dev/null
+++ b/lib/manager/html/extract.ts
@@ -0,0 +1,46 @@
+import { PackageFile, PackageDependency } from '../common';
+import { DATASOURCE_CDNJS } from '../../constants/data-binary-source';
+import { cloudflareUrlRegex } from '../cdnurl/extract';
+
+const regex = /<\s*(script|link)\s+[^>]*?\/?>/i;
+
+export function extractDep(tag: string): PackageDependency | null {
+  const match = cloudflareUrlRegex.exec(tag);
+  if (match) {
+    const { depName, currentValue, asset } = match.groups;
+    return {
+      datasource: DATASOURCE_CDNJS,
+      depName,
+      lookupName: `${depName}/${asset}`,
+      currentValue,
+    };
+  }
+  return null;
+}
+
+export function extractPackageFile(content: string): PackageFile {
+  const deps: PackageDependency[] = [];
+
+  let rest = content;
+  let match = regex.exec(rest);
+  let offset = 0;
+  while (match) {
+    const [tag] = match;
+    const tagLength = tag.length;
+    const tagPosition = offset + match.index;
+
+    offset += match.index + tag.length;
+    rest = content.slice(offset);
+    match = regex.exec(rest);
+
+    const dep = extractDep(tag);
+    if (dep) {
+      deps.push({
+        ...dep,
+        managerData: { tagLength, tagPosition },
+      });
+    }
+  }
+
+  return { deps };
+}
diff --git a/lib/manager/html/index.ts b/lib/manager/html/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..beaa7d4bed690af46e141b1f817f7be146ee1a02
--- /dev/null
+++ b/lib/manager/html/index.ts
@@ -0,0 +1,10 @@
+import { extractPackageFile } from './extract';
+import { updateDependency } from './update';
+import { VERSION_SCHEME_SEMVER } from '../../constants/version-schemes';
+
+export { extractPackageFile, updateDependency };
+
+export const defaultConfig = {
+  fileMatch: ['\\.html?$'],
+  versionScheme: VERSION_SCHEME_SEMVER,
+};
diff --git a/lib/manager/html/update.spec.ts b/lib/manager/html/update.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d3912ec548bc1e862e4571dc35ade4881dc49fdf
--- /dev/null
+++ b/lib/manager/html/update.spec.ts
@@ -0,0 +1,81 @@
+import { readFileSync } from 'fs';
+import { resolve } from 'path';
+import { extractPackageFile, updateDependency } from '.';
+import _got from '../../util/got';
+
+const got: jest.Mock<any> = _got as any;
+jest.mock('../../util/got');
+
+const content = readFileSync(
+  resolve(__dirname, `./__fixtures__/sample.html`),
+  'utf8'
+);
+
+const axiosJson = JSON.parse(
+  readFileSync(resolve(__dirname, `./__fixtures__/axios.json`), 'utf8')
+);
+
+describe('manager/html/update', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+    return global.renovateCache.rmAll();
+  });
+  it('updates dependency', async () => {
+    got.mockResolvedValueOnce({ body: axiosJson });
+    const { deps } = extractPackageFile(content);
+    const dep = deps.pop();
+    const upgrade = {
+      ...dep,
+      newValue: '0.19.2',
+    };
+    const { currentValue, newValue } = upgrade;
+    const newFileContent = await updateDependency(content, upgrade);
+    const cmpContent = content
+      .replace(currentValue, newValue)
+      .replace(
+        'sha256-mpnrJ5DpEZZkwkE1ZgkEQQJW/46CSEh/STrZKOB/qoM=',
+        'sha256-T/f7Sju1ZfNNfBh7skWn0idlCBcI3RwdLSS4/I7NQKQ='
+      );
+    expect(newFileContent).toEqual(cmpContent);
+  });
+  it('returns same string for already updated dependency', async () => {
+    const { deps } = extractPackageFile(content);
+    const dep = deps.pop();
+    const upgrade = {
+      ...dep,
+      newValue: '9.9.999',
+    };
+    const { currentValue } = upgrade;
+    const alreadyUpdated = content
+      .replace(currentValue, '9.9.999')
+      .replace(
+        'sha256-mpnrJ5DpEZZkwkE1ZgkEQQJW/46CSEh/STrZKOB/qoM=',
+        'sha256-T/f7Sju1ZfNNfBh7skWn0idlCBcI3RwdLSS4/I7NQKQ='
+      );
+    const newFileContent = await updateDependency(alreadyUpdated, upgrade);
+    expect(newFileContent).toBe(alreadyUpdated);
+  });
+  it('returns null if content has changed', async () => {
+    const { deps } = extractPackageFile(content);
+    const dep = deps.pop();
+    const upgrade = {
+      ...dep,
+      newValue: '9.9.999',
+    };
+    const { currentValue } = upgrade;
+    const alreadyUpdated = content.replace(currentValue, '2020.1');
+    const newFileContent = await updateDependency(alreadyUpdated, upgrade);
+    expect(newFileContent).toBeNull();
+  });
+  it('returns null if hash is not found', async () => {
+    got.mockResolvedValueOnce({ body: axiosJson });
+    const { deps } = extractPackageFile(content);
+    const dep = deps.pop();
+    const upgrade = {
+      ...dep,
+      newValue: '9.9.999',
+    };
+    const newFileContent = await updateDependency(content, upgrade);
+    expect(newFileContent).toBeNull();
+  });
+});
diff --git a/lib/manager/html/update.ts b/lib/manager/html/update.ts
new file mode 100644
index 0000000000000000000000000000000000000000..12d15a3dabbdbebc849f85b938f7615c7d31d926
--- /dev/null
+++ b/lib/manager/html/update.ts
@@ -0,0 +1,67 @@
+import { logger } from '../../logger';
+import { PackageDependency, Upgrade } from '../common';
+import { extractDep } from './extract';
+import * as cdnjs from '../../datasource/cdnjs';
+import got from '../../util/got';
+import { CdnjsAsset } from '../../datasource/cdnjs';
+
+const integrityRegexp = /\s+integrity\s*=\s*"(?<hash>[^"]+)"/;
+
+function extractHash(tag: string): string | null {
+  let result = null;
+  const match = integrityRegexp.exec(tag);
+  if (match) result = match.groups.hash;
+  return result;
+}
+
+async function fetchNewHash(
+  dep: PackageDependency,
+  newValue: string
+): Promise<string | null> {
+  let result = null;
+  const { depName, lookupName } = dep;
+  const url = cdnjs.depUrl(depName);
+  const assetName = lookupName.replace(`${depName}/`, '');
+
+  let res = null;
+  try {
+    res = await got(url, { json: true });
+  } catch (e) /* istanbul ignore next */ {
+    return null;
+  }
+
+  const assets: CdnjsAsset[] = res.body && res.body.assets;
+  const asset = assets && assets.find(({ version }) => version === newValue);
+  const hash = asset && asset.sri && asset.sri[assetName];
+  if (hash) result = hash;
+  return result;
+}
+
+export async function updateDependency(
+  fileContent: string,
+  upgrade: Upgrade
+): Promise<string | null> {
+  const { currentValue, newValue, managerData } = upgrade;
+  const { tagPosition, tagLength } = managerData;
+  const leftPart = fileContent.slice(0, tagPosition);
+  const tagPart = fileContent.slice(tagPosition, tagPosition + tagLength);
+  const rightPart = fileContent.slice(tagPosition + tagLength);
+  const dep = extractDep(tagPart);
+  if (dep.currentValue === newValue) {
+    return fileContent;
+  }
+  if (dep.currentValue === currentValue) {
+    const currentHash = extractHash(tagPart);
+    let tag = tagPart.replace(currentValue, newValue);
+    if (currentHash) {
+      const newHash = await fetchNewHash(dep, newValue);
+      if (!newHash) {
+        logger.error(`Could not upgrade SRI hash`);
+        return null;
+      }
+      tag = tag.replace(currentHash, newHash);
+    }
+    return `${leftPart}${tag}${rightPart}`;
+  }
+  return null;
+}