diff --git a/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap b/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap
index b21eac557d17a87f99551935a03214b389337916..0abab7674b2c197d47eae457d7582f0990bf0590 100644
--- a/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap
+++ b/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap
@@ -45,29 +45,6 @@ Array [
 ]
 `;
 
-exports[`manager/npm/post-update/npm massages lock files 1`] = `
-Array [
-  Object {
-    "cmd": "npm install --package-lock-only --no-audit --ignore-scripts",
-    "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",
-      },
-      "maxBuffer": 10485760,
-      "timeout": 900000,
-    },
-  },
-]
-`;
-
 exports[`manager/npm/post-update/npm performs full install 1`] = `Array []`;
 
 exports[`manager/npm/post-update/npm performs lock file maintenance 1`] = `
diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts
index dc83a1ca9495515cc7d37f922c8a76b24f53b5d3..636ca8b5cb355a61839b1f716240f2eb94e12775 100644
--- a/lib/manager/npm/post-update/index.ts
+++ b/lib/manager/npm/post-update/index.ts
@@ -167,7 +167,10 @@ export async function writeExistingFiles(
       } else {
         logger.debug(`Writing ${npmLock}`);
         let existingNpmLock = await getFile(npmLock);
+        const npmLockParsed = JSON.parse(existingNpmLock);
+        const packageNames = Object.keys(npmLockParsed?.packages || {}); // lockfileVersion=2
         const widens = [];
+        let lockFileChanged = false;
         for (const upgrade of config.upgrades) {
           if (
             upgrade.rangeStrategy === 'widen' &&
@@ -175,19 +178,29 @@ export async function writeExistingFiles(
           ) {
             widens.push(upgrade.depName);
           }
+          const { depName } = upgrade;
+          for (const packageName of packageNames) {
+            if (
+              packageName === `node_modules/${depName}` ||
+              packageName.startsWith(`node_modules/${depName}/`)
+            ) {
+              logger.trace({ packageName }, 'Massaging out package name');
+              lockFileChanged = true;
+              delete npmLockParsed.packages[packageName];
+            }
+          }
         }
         if (widens.length) {
           logger.debug(
             `Removing ${String(widens)} from ${npmLock} to force an update`
           );
+          lockFileChanged = true;
           try {
-            const npmLockParsed = JSON.parse(existingNpmLock);
             if (npmLockParsed.dependencies) {
               widens.forEach((depName) => {
                 delete npmLockParsed.dependencies[depName];
               });
             }
-            existingNpmLock = JSON.stringify(npmLockParsed, null, 2);
           } catch (err) {
             logger.warn(
               { npmLock },
@@ -195,6 +208,10 @@ export async function writeExistingFiles(
             );
           }
         }
+        if (lockFileChanged) {
+          logger.debug('Massaging npm lock file before writing to disk');
+          existingNpmLock = JSON.stringify(npmLockParsed, null, 2);
+        }
         await outputFile(npmLockPath, existingNpmLock);
       }
     }
diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts
index 4fd11cf91c3e64b7804d36f0878eb5be4c33f285..e4f9341151427be2b7b907f2b7f5a208fc1b8552 100644
--- a/lib/manager/npm/post-update/npm.spec.ts
+++ b/lib/manager/npm/post-update/npm.spec.ts
@@ -1,5 +1,4 @@
 import { exec as _exec } from 'child_process';
-import * as fsExtra from 'fs-extra';
 import upath from 'upath';
 
 import { envMock, mockExecAll } from '../../../../test/exec-util';
@@ -38,38 +37,11 @@ describe('manager/npm/post-update/npm', () => {
       { skipInstalls, postUpdateOptions },
       updates
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.error).toBeUndefined();
     expect(res.lockFile).toBe('package-lock-contents');
     expect(execSnapshots).toMatchSnapshot();
   });
-  it('massages lock files', async () => {
-    const execSnapshots = mockExecAll(exec);
-    const lockContents = await fsExtra.readFile(
-      upath.join(__dirname, '/__fixtures__/massage1/package-lock.json'),
-      'utf8'
-    );
-    fs.readFile = jest.fn(() => lockContents) as never;
-    const skipInstalls = true;
-    const updates = [
-      {
-        depName: '@storybook/vue',
-        newVersion: '6.3.12',
-        isLockfileUpdate: false,
-      },
-    ];
-    const res = await npmHelper.generateLockFile(
-      'some-dir',
-      {},
-      'package-lock.json',
-      { skipInstalls },
-      updates
-    );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
-    expect(fs.outputFile).toHaveBeenCalledTimes(1);
-    expect(res.error).toBeUndefined();
-    expect(execSnapshots).toMatchSnapshot();
-  });
   it('performs lock file updates', async () => {
     const execSnapshots = mockExecAll(exec);
     fs.readFile = jest.fn(() => 'package-lock-contents') as never;
@@ -84,7 +56,7 @@ describe('manager/npm/post-update/npm', () => {
       { skipInstalls },
       updates
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.error).toBeUndefined();
     expect(res.lockFile).toBe('package-lock-contents');
     expect(execSnapshots).toMatchSnapshot();
@@ -109,7 +81,7 @@ describe('manager/npm/post-update/npm', () => {
       upath.join('some-dir', 'package-lock.json'),
       upath.join('some-dir', 'npm-shrinkwrap.json')
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(fs.readFile).toHaveBeenCalledWith(
       upath.join('some-dir', 'npm-shrinkwrap.json'),
       'utf8'
@@ -134,7 +106,7 @@ describe('manager/npm/post-update/npm', () => {
       upath.join('some-dir', 'package-lock.json')
     );
     expect(fs.move).toHaveBeenCalledTimes(0);
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(fs.readFile).toHaveBeenCalledWith(
       upath.join('some-dir', 'npm-shrinkwrap.json'),
       'utf8'
@@ -154,7 +126,7 @@ describe('manager/npm/post-update/npm', () => {
       'package-lock.json',
       { skipInstalls, binarySource }
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.error).toBeUndefined();
     expect(res.lockFile).toBe('package-lock-contents');
     expect(execSnapshots).toMatchSnapshot();
@@ -170,7 +142,7 @@ describe('manager/npm/post-update/npm', () => {
       { binarySource },
       [{ isRemediation: true }]
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.error).toBeUndefined();
     expect(res.lockFile).toBe('package-lock-contents');
     expect(execSnapshots).toHaveLength(2);
@@ -185,7 +157,7 @@ describe('manager/npm/post-update/npm', () => {
       {},
       'package-lock.json'
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.error).toBeTrue();
     expect(res.lockFile).toBeUndefined();
     expect(execSnapshots).toMatchSnapshot();
@@ -198,7 +170,7 @@ describe('manager/npm/post-update/npm', () => {
       {},
       'package-lock.json'
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.lockFile).toBe('package-lock-contents');
     expect(execSnapshots).toMatchSnapshot();
   });
@@ -211,7 +183,7 @@ describe('manager/npm/post-update/npm', () => {
       'package-lock.json',
       { binarySource: 'docker', constraints: { npm: '^6.0.0' } }
     );
-    expect(fs.readFile).toHaveBeenCalledTimes(2);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.lockFile).toBe('package-lock-contents');
     expect(execSnapshots).toMatchSnapshot();
   });
diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts
index 9dd5414dcdd478ebb3f19efd6fb5541f2ba0359f..f84023593c5ceccf9a2483ef6ba5964b4e7b5552 100644
--- a/lib/manager/npm/post-update/npm.ts
+++ b/lib/manager/npm/post-update/npm.ts
@@ -1,4 +1,3 @@
-import is from '@sindresorhus/is';
 import { validRange } from 'semver';
 import { quote } from 'shlex';
 import { join } from 'upath';
@@ -9,13 +8,7 @@ import {
 } from '../../../constants/error-messages';
 import { logger } from '../../../logger';
 import { ExecOptions, exec } from '../../../util/exec';
-import {
-  move,
-  outputFile,
-  pathExists,
-  readFile,
-  remove,
-} from '../../../util/fs';
+import { move, pathExists, readFile, remove } from '../../../util/fs';
 import type { PostUpdateConfig, Upgrade } from '../../types';
 import { getNodeConstraint } from './node-version';
 import type { GenerateLockFileResult } from './types';
@@ -111,6 +104,7 @@ export async function generateLockFile(
       commands.push('npm dedupe');
     }
 
+    // TODO: don't assume package-lock.json is in the same directory
     const lockFileName = join(cwd, filename);
 
     if (upgrades.find((upgrade) => upgrade.isLockFileMaintenance)) {
@@ -125,36 +119,6 @@ export async function generateLockFile(
           'Error removing yarn.lock for lock file maintenance'
         );
       }
-    } else {
-      // massage lock file for npm 7+
-      try {
-        const lockFileParsed = JSON.parse(await readFile(lockFileName, 'utf8'));
-        if (is.plainObject(lockFileParsed.packages)) {
-          const packageNames = Object.keys(lockFileParsed.packages);
-          let lockFileMassaged = false;
-          for (const { depName } of upgrades) {
-            for (const packageName of packageNames) {
-              if (
-                packageName === `node_modules/${depName}` ||
-                packageName.startsWith(`node_modules/${depName}/`)
-              ) {
-                logger.trace({ packageName }, 'Massaging out package name');
-                lockFileMassaged = true;
-                delete lockFileParsed.packages[packageName];
-              }
-            }
-          }
-          if (lockFileMassaged) {
-            logger.debug('Writing massaged package-lock.json');
-            await outputFile(
-              lockFileName,
-              JSON.stringify(lockFileParsed, null, 2)
-            );
-          }
-        }
-      } catch (err) {
-        logger.warn({ err }, 'Error massaging package-lock.json');
-      }
     }
 
     // Run the commands