diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index bb56cd6c44df80d7f1ff0f598801763ab9cbc150..3d5907b0f4e29c46e722b2defa152773add610bc 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -1102,7 +1102,7 @@ If enabled Renovate will pin docker images by means of their sha256 digest and n
 - `gomodTidy`: Run `go mod tidy` after Go module updates
 - `npmDedupe`: Run `npm dedupe` after `package-lock.json` updates
 - `yarnDedupeFewer`: Run `yarn-deduplicate --strategy fewer` after `yarn.lock` updates
-- `yarnDedupeHighest`: Run `yarn-deduplicate --strategy highest` after `yarn.lock` updates
+- `yarnDedupeHighest`: Run `yarn-deduplicate --strategy highest` (`yarn dedupe --strategy highest` for Yarn >=2.2.0) after `yarn.lock` updates
 
 ## postUpgradeTasks
 
diff --git a/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap b/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
index 5351e93ad0117dd1adc44da722c36cdf8aae5f76..9d979942b9f9822b19025c3c7d84a2bb9ad599ce 100644
--- a/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
+++ b/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
@@ -136,6 +136,49 @@ Array [
 ]
 `;
 
+exports[`manager/npm/post-update/yarn generates lock files using yarn v2.2.0 1`] = `
+Array [
+  Object {
+    "cmd": "yarn install",
+    "options": Object {
+      "cwd": "some-dir",
+      "encoding": "utf-8",
+      "env": Object {
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+        "YARN_ENABLE_SCRIPTS": "0",
+        "YARN_HTTP_TIMEOUT": "100000",
+      },
+      "timeout": 900000,
+    },
+  },
+  Object {
+    "cmd": "yarn dedupe --strategy highest",
+    "options": Object {
+      "cwd": "some-dir",
+      "encoding": "utf-8",
+      "env": Object {
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+        "YARN_ENABLE_SCRIPTS": "0",
+        "YARN_HTTP_TIMEOUT": "100000",
+      },
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
 exports[`manager/npm/post-update/yarn performs lock file maintenance using yarn v1.22.0 1`] = `
 Array [
   Object {
@@ -250,6 +293,49 @@ Array [
 ]
 `;
 
+exports[`manager/npm/post-update/yarn performs lock file maintenance using yarn v2.2.0 1`] = `
+Array [
+  Object {
+    "cmd": "yarn install",
+    "options": Object {
+      "cwd": "some-dir",
+      "encoding": "utf-8",
+      "env": Object {
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+        "YARN_ENABLE_SCRIPTS": "0",
+        "YARN_HTTP_TIMEOUT": "100000",
+      },
+      "timeout": 900000,
+    },
+  },
+  Object {
+    "cmd": "yarn dedupe --strategy highest",
+    "options": Object {
+      "cwd": "some-dir",
+      "encoding": "utf-8",
+      "env": Object {
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+        "YARN_ENABLE_SCRIPTS": "0",
+        "YARN_HTTP_TIMEOUT": "100000",
+      },
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
 exports[`manager/npm/post-update/yarn performs lock file updates and full install using yarn v1.22.0 1`] = `
 Array [
   Object {
diff --git a/lib/manager/npm/post-update/yarn.spec.ts b/lib/manager/npm/post-update/yarn.spec.ts
index ad726a0c985a83264f24299b81e479591525ba99..4d154a37dbc8338497ef157fb0c4ba37a5990701 100644
--- a/lib/manager/npm/post-update/yarn.spec.ts
+++ b/lib/manager/npm/post-update/yarn.spec.ts
@@ -29,11 +29,12 @@ describe(getName(__filename), () => {
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
   });
   it.each([
-    ['1.22.0', 2],
-    ['2.1.0', 1],
+    ['1.22.0', '^1.10.0', 2],
+    ['2.1.0', '>= 2.0.0', 1],
+    ['2.2.0', '2.2.0', 1],
   ])(
     'generates lock files using yarn v%s',
-    async (yarnVersion, expectedFsCalls) => {
+    async (yarnVersion, yarnCompatibility, expectedFsCalls) => {
       const execSnapshots = mockExecAll(exec, {
         stdout: yarnVersion,
         stderr: '',
@@ -49,7 +50,7 @@ describe(getName(__filename), () => {
       const config = {
         dockerMapDotfiles: true,
         compatibility: {
-          yarn: yarnVersion === '1.22.0' ? '^1.10.0' : '>= 2.0.0',
+          yarn: yarnCompatibility,
         },
         postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
       };
@@ -103,11 +104,12 @@ describe(getName(__filename), () => {
     }
   );
   it.each([
-    ['1.22.0', 2],
-    ['2.1.0', 1],
+    ['1.22.0', '^1.10.0', 2],
+    ['2.1.0', '>= 2.0.0', 1],
+    ['2.2.0', '2.2.0', 1],
   ])(
     'performs lock file maintenance using yarn v%s',
-    async (yarnVersion, expectedFsCalls) => {
+    async (yarnVersion, yarnCompatibility, expectedFsCalls) => {
       const execSnapshots = mockExecAll(exec, {
         stdout: yarnVersion,
         stderr: '',
@@ -123,7 +125,7 @@ describe(getName(__filename), () => {
       const config = {
         dockerMapDotfiles: true,
         compatibility: {
-          yarn: yarnVersion === '1.22.0' ? '^1.10.0' : '>= 2.0.0',
+          yarn: yarnCompatibility,
         },
         postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
       };
diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts
index 667ca710e6c137ee942fdcd358c1b03ed2c43e98..3b6adf166abb58dd5be94d0b6724458ea072212d 100644
--- a/lib/manager/npm/post-update/yarn.ts
+++ b/lib/manager/npm/post-update/yarn.ts
@@ -1,5 +1,5 @@
 import is from '@sindresorhus/is';
-import { minVersion, validRange } from 'semver';
+import { gte, minVersion, validRange } from 'semver';
 import { quote } from 'shlex';
 import { join } from 'upath';
 import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
@@ -48,12 +48,14 @@ export async function generateLockFile(
   let lockFile = null;
   try {
     const yarnCompatibility = config.compatibility?.yarn;
-    const isValidYarnRange = validRange(yarnCompatibility);
-    const isYarn1 =
-      !isValidYarnRange || minVersion(yarnCompatibility).major === 1;
+    const minYarnVersion =
+      validRange(yarnCompatibility) && minVersion(yarnCompatibility);
+    const isYarn1 = !minYarnVersion || minYarnVersion.major === 1;
+    const isYarnDedupeAvailable =
+      minYarnVersion && gte(minYarnVersion, '2.2.0');
 
     let installYarn = 'npm i -g yarn';
-    if (isYarn1 && isValidYarnRange) {
+    if (isYarn1 && minYarnVersion) {
       installYarn += `@${quote(yarnCompatibility)}`;
     }
 
@@ -133,11 +135,18 @@ export async function generateLockFile(
       // Run yarn again in case any changes are necessary
       commands.push(`yarn install ${cmdOptions}`.trim());
     }
-    if (isYarn1 && config.postUpdateOptions?.includes('yarnDedupeHighest')) {
+    if (
+      (isYarn1 || isYarnDedupeAvailable) &&
+      config.postUpdateOptions?.includes('yarnDedupeHighest')
+    ) {
       logger.debug('Performing yarn dedupe highest');
-      commands.push('npx yarn-deduplicate --strategy highest');
-      // Run yarn again in case any changes are necessary
-      commands.push(`yarn install ${cmdOptions}`.trim());
+      if (isYarn1) {
+        commands.push('npx yarn-deduplicate --strategy highest');
+        // Run yarn again in case any changes are necessary
+        commands.push(`yarn install ${cmdOptions}`.trim());
+      } else {
+        commands.push('yarn dedupe --strategy highest');
+      }
     }
 
     if (upgrades.find((upgrade) => upgrade.isLockFileMaintenance)) {