diff --git a/lib/workers/package/versions.js b/lib/workers/package/versions.js
index d8ac5762ab83f7b0e32ff1c7498039db2061c4e2..0d3f83f87bcc0a5ec9e5a1ca1af8e5c9abb7af56 100644
--- a/lib/workers/package/versions.js
+++ b/lib/workers/package/versions.js
@@ -172,9 +172,14 @@ function determineUpgrades(npmDep, config) {
   // Check if it's a range type we support
   const semverParsed = semverUtils.parseRange(currentVersion);
   // Check the "last" part, which is also the first and only if it's a simple semver
-  const [currentSemver] = semverParsed.slice(-1);
+  const [lastSemver] = semverParsed.slice(-1);
+  const secondLastSemver = semverParsed[semverParsed.length - 2];
   if (semverParsed.length > 1) {
-    if (currentSemver.operator !== '<' && currentSemver.operator !== '<=') {
+    if (lastSemver.operator === '<' || lastSemver.operator === '<=') {
+      logger.debug('Found less than range');
+    } else if (secondLastSemver.operator === '||') {
+      logger.debug('Found an OR range');
+    } else {
       // We don't know how to support complex semver ranges, so don't upgrade
       result.message = `Complex semver ranges such as "${currentVersion}" are not yet supported so will be skipped`;
       logger.info(
@@ -183,14 +188,13 @@ function determineUpgrades(npmDep, config) {
       );
       return [result];
     }
-    logger.debug('Found less than range');
   }
   // Loop through all upgrades and convert to ranges
   const rangedUpgrades = _(upgrades)
     .map(upgrade => ({ ...upgrade, ...{ isRange: true } }))
     .map(upgrade => {
       const { major, minor } = semverUtils.parse(upgrade.newVersion);
-      if (currentSemver.operator === '~') {
+      if (lastSemver.operator === '~' && semverParsed.length === 1) {
         // Utilise that a.b is the same as ~a.b.0
         const minSatisfying = semver.minSatisfying(
           versionList,
@@ -198,24 +202,44 @@ function determineUpgrades(npmDep, config) {
         );
         // Add a tilde before that version number
         return { ...upgrade, ...{ newVersion: `~${minSatisfying}` } };
-      } else if (currentSemver.operator === '^') {
+      } else if (lastSemver.operator === '~' && semverParsed.length > 1) {
+        // Utilise that a.b is the same as ~a.b.0
+        const minSatisfying = semver.minSatisfying(
+          versionList,
+          `${major}.${minor}`
+        );
+        // Add a tilde before that version number
+        const newVersion = `~${minSatisfying}`;
+        return {
+          ...upgrade,
+          newVersion: currentVersion + ' || ' + newVersion,
+        };
+      } else if (lastSemver.operator === '^' && semverParsed.length === 1) {
+        let newVersion;
         // Special case where major and minor are 0
         if (major === '0' && minor === '0') {
-          return {
-            ...upgrade,
-            ...{
-              newVersion: `^${upgrade.newVersion}`,
-            },
-          };
+          newVersion = `^${upgrade.newVersion}`;
+        } else {
+          // If version is < 1, then semver treats ^ same as ~
+          const newRange = major === '0' ? `${major}.${minor}` : `${major}`;
+          const minSatisfying = semver.minSatisfying(versionList, newRange);
+          // Add in the caret
+          newVersion = `^${minSatisfying}`;
         }
+        return { ...upgrade, newVersion };
+      } else if (lastSemver.operator === '^' && semverParsed.length > 1) {
         // If version is < 1, then semver treats ^ same as ~
         const newRange = major === '0' ? `${major}.${minor}` : `${major}`;
         const minSatisfying = semver.minSatisfying(versionList, newRange);
         // Add in the caret
-        return { ...upgrade, ...{ newVersion: `^${minSatisfying}` } };
-      } else if (currentSemver.operator === '<=') {
-        const minorZero = !currentSemver.minor || currentSemver.minor === '0';
-        const patchZero = !currentSemver.patch || currentSemver.patch === '0';
+        const newVersion = `${currentVersion} || ^${minSatisfying}`;
+        return {
+          ...upgrade,
+          newVersion,
+        };
+      } else if (lastSemver.operator === '<=') {
+        const minorZero = !lastSemver.minor || lastSemver.minor === '0';
+        const patchZero = !lastSemver.patch || lastSemver.patch === '0';
         const newRange = [...semverParsed];
         if (minorZero && patchZero) {
           logger.debug('Found a less than major');
@@ -238,9 +262,9 @@ function determineUpgrades(npmDep, config) {
         }
         const newVersion = semverUtils.stringifyRange(newRange);
         return { ...upgrade, newVersion };
-      } else if (currentSemver.operator === '<') {
-        const minorZero = !currentSemver.minor || currentSemver.minor === '0';
-        const patchZero = !currentSemver.patch || currentSemver.patch === '0';
+      } else if (lastSemver.operator === '<') {
+        const minorZero = !lastSemver.minor || lastSemver.minor === '0';
+        const patchZero = !lastSemver.patch || lastSemver.patch === '0';
         const newRange = [...semverParsed];
         if (minorZero && patchZero) {
           logger.debug('Found a less than major');
@@ -263,16 +287,16 @@ function determineUpgrades(npmDep, config) {
         }
         const newVersion = semverUtils.stringifyRange(newRange);
         return { ...upgrade, newVersion };
-      } else if (currentSemver.minor === undefined) {
+      } else if (lastSemver.minor === undefined) {
         // Example: 1
         return { ...upgrade, ...{ newVersion: `${major}` } };
-      } else if (currentSemver.minor === 'x') {
+      } else if (lastSemver.minor === 'x') {
         // Example: 1.x
         return { ...upgrade, ...{ newVersion: `${major}.x` } };
-      } else if (currentSemver.patch === undefined) {
+      } else if (lastSemver.patch === undefined) {
         // Example: 1.2
         return { ...upgrade, ...{ newVersion: `${major}.${minor}` } };
-      } else if (currentSemver.patch === 'x') {
+      } else if (lastSemver.patch === 'x') {
         // Example: 1.2.x
         return { ...upgrade, ...{ newVersion: `${major}.${minor}.x` } };
       }
diff --git a/test/workers/package/__snapshots__/versions.spec.js.snap b/test/workers/package/__snapshots__/versions.spec.js.snap
index 0c481d3f9d05789d3f9ba2d1b753cd1496b772d6..a7b4c2c4115e1af2e13c70bf6879a2fbc5ef8905 100644
--- a/test/workers/package/__snapshots__/versions.spec.js.snap
+++ b/test/workers/package/__snapshots__/versions.spec.js.snap
@@ -37,13 +37,6 @@ Array [
 ]
 `;
 
-exports[`workers/package/versions .determineUpgrades(npmDep, config) ignores complex ranges when not pinning 1`] = `
-Object {
-  "message": "Complex semver ranges such as \\"^0.7.0 || ^0.8.0\\" are not yet supported so will be skipped",
-  "type": "warning",
-}
-`;
-
 exports[`workers/package/versions .determineUpgrades(npmDep, config) ignores pinning for ranges when other upgrade exists 1`] = `
 Array [
   Object {
@@ -354,6 +347,52 @@ Array [
 ]
 `;
 
+exports[`workers/package/versions .determineUpgrades(npmDep, config) supports complex major ranges 1`] = `
+Array [
+  Object {
+    "changeLogFromVersion": "2.7.0",
+    "changeLogToVersion": "3.8.1",
+    "isMajor": true,
+    "isRange": true,
+    "newVersion": "^1.0.0 || ^2.0.0 || ^3.0.0",
+    "newVersionMajor": 3,
+    "newVersionMinor": 8,
+    "type": "major",
+    "unpublishable": false,
+  },
+]
+`;
+
+exports[`workers/package/versions .determineUpgrades(npmDep, config) supports complex ranges 1`] = `
+Object {
+  "changeLogFromVersion": "0.8.12",
+  "changeLogToVersion": "0.9.7",
+  "isMinor": true,
+  "isRange": true,
+  "newVersion": "^0.7.0 || ^0.8.0 || ^0.9.0",
+  "newVersionMajor": 0,
+  "newVersionMinor": 9,
+  "type": "minor",
+  "unpublishable": false,
+}
+`;
+
+exports[`workers/package/versions .determineUpgrades(npmDep, config) supports complex tilde ranges 1`] = `
+Array [
+  Object {
+    "changeLogFromVersion": "1.3.0",
+    "changeLogToVersion": "1.4.1",
+    "isMinor": true,
+    "isRange": true,
+    "newVersion": "~1.2.0 || ~1.3.0 || ~1.4.0",
+    "newVersionMajor": 1,
+    "newVersionMinor": 4,
+    "type": "minor",
+    "unpublishable": false,
+  },
+]
+`;
+
 exports[`workers/package/versions .determineUpgrades(npmDep, config) supports future versions if already future 1`] = `
 Array [
   Object {
diff --git a/test/workers/package/versions.spec.js b/test/workers/package/versions.spec.js
index 57e1960b647a2eaa62427ae246da4c81adea304b..872d5efde8de6afce3688fce1b41270ceb9dd3aa 100644
--- a/test/workers/package/versions.spec.js
+++ b/test/workers/package/versions.spec.js
@@ -156,13 +156,25 @@ describe('workers/package/versions', () => {
       config.currentVersion = '^0.7.0';
       expect(versions.determineUpgrades(qJson, config)).toMatchSnapshot();
     });
-    it('ignores complex ranges when not pinning', () => {
+    it('supports complex ranges', () => {
       config.pinVersions = false;
       config.currentVersion = '^0.7.0 || ^0.8.0';
       const res = versions.determineUpgrades(qJson, config);
-      expect(res).toHaveLength(1);
+      expect(res).toHaveLength(2);
       expect(res[0]).toMatchSnapshot();
     });
+    it('supports complex major ranges', () => {
+      config.pinVersions = false;
+      config.currentVersion = '^1.0.0 || ^2.0.0';
+      const res = versions.determineUpgrades(webpackJson, config);
+      expect(res).toMatchSnapshot();
+    });
+    it('supports complex tilde ranges', () => {
+      config.pinVersions = false;
+      config.currentVersion = '~1.2.0 || ~1.3.0';
+      const res = versions.determineUpgrades(qJson, config);
+      expect(res).toMatchSnapshot();
+    });
     it('returns nothing for greater than ranges', () => {
       config.pinVersions = false;
       config.currentVersion = '>= 0.7.0';