diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts
index 093fad3a52e496122926e4111dc728c0485d8b19..390ced0faaf0f5f044949e0155eaa07003eeb475 100644
--- a/lib/manager/npm/post-update/index.ts
+++ b/lib/manager/npm/post-update/index.ts
@@ -1,20 +1,19 @@
 import path from 'path';
+import upath from 'upath';
+import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
+import { id as npmId } from '../../../datasource/npm';
+import { logger } from '../../../logger';
+import { ExternalHostError } from '../../../types/errors/external-host-error';
+import { getChildProcessEnv } from '../../../util/exec/env';
 import {
+  deleteLocalFile,
   ensureDir,
   outputFile,
   readFile,
   remove,
   unlink,
   writeFile,
-} from 'fs-extra';
-import upath from 'upath';
-// eslint-disable-next-line import/no-unresolved
-import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
-import { id as npmId } from '../../../datasource/npm';
-import { logger } from '../../../logger';
-import { ExternalHostError } from '../../../types/errors/external-host-error';
-import { getChildProcessEnv } from '../../../util/exec/env';
-import { deleteLocalFile } from '../../../util/fs';
+} from '../../../util/fs';
 import { branchExists, getFile, getRepoStatus } from '../../../util/git';
 import * as hostRules from '../../../util/host-rules';
 import { PackageFile, PostUpdateConfig, Upgrade } from '../../common';
diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts
index eaa0bd421e37b2e99c4d4c6d9c4172114d997236..bac9acd302963b70659e7c770eb3936496a96074 100644
--- a/lib/manager/npm/post-update/npm.spec.ts
+++ b/lib/manager/npm/post-update/npm.spec.ts
@@ -1,15 +1,15 @@
 import { exec as _exec } from 'child_process';
 import path from 'path';
-import _fs from 'fs-extra';
 import { envMock, mockExecAll } from '../../../../test/execUtil';
 import { mocked } from '../../../../test/util';
 import { BinarySource } from '../../../util/exec/common';
 import * as _env from '../../../util/exec/env';
+import * as _fs from '../../../util/fs/proxies';
 import * as npmHelper from './npm';
 
-jest.mock('fs-extra');
 jest.mock('child_process');
 jest.mock('../../../util/exec/env');
+jest.mock('../../../util/fs/proxies');
 jest.mock('./node-version');
 
 const exec: jest.Mock<typeof _exec> = _exec as any;
@@ -64,7 +64,7 @@ describe('generateLockFile', () => {
   });
   it('performs npm-shrinkwrap.json updates', async () => {
     const execSnapshots = mockExecAll(exec);
-    fs.pathExists.mockImplementationOnce(() => true);
+    fs.pathExists.mockResolvedValueOnce(true);
     fs.move = jest.fn();
     fs.readFile = jest.fn(() => 'package-lock-contents') as never;
     const skipInstalls = true;
@@ -93,7 +93,7 @@ describe('generateLockFile', () => {
   });
   it('performs npm-shrinkwrap.json updates (no package-lock.json)', async () => {
     const execSnapshots = mockExecAll(exec);
-    fs.pathExists.mockImplementationOnce(() => false);
+    fs.pathExists.mockResolvedValueOnce(false);
     fs.move = jest.fn();
     fs.readFile = jest.fn((_, _1) => 'package-lock-contents') as never;
     const skipInstalls = true;
diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts
index 1bfe12b5fc5b2f8f711a4a99f03406cd6fb6bb9e..62c85b683330e455a6ef35ee7cd19f636907c504 100644
--- a/lib/manager/npm/post-update/npm.ts
+++ b/lib/manager/npm/post-update/npm.ts
@@ -1,10 +1,10 @@
-import { move, pathExists, readFile, remove } from 'fs-extra';
 import { validRange } from 'semver';
 import { quote } from 'shlex';
 import { join } from 'upath';
 import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
 import { logger } from '../../../logger';
 import { ExecOptions, exec } from '../../../util/exec';
+import { move, pathExists, readFile, remove } from '../../../util/fs';
 import { PostUpdateConfig, Upgrade } from '../../common';
 import { getNodeConstraint } from './node-version';
 
diff --git a/lib/manager/npm/post-update/pnpm.spec.ts b/lib/manager/npm/post-update/pnpm.spec.ts
index 8871e4002339c90fe386f560eabf50602c13a44e..d79995ee8f9ce261dbb923d1a2f8b9780db2cf57 100644
--- a/lib/manager/npm/post-update/pnpm.spec.ts
+++ b/lib/manager/npm/post-update/pnpm.spec.ts
@@ -1,14 +1,14 @@
 import { exec as _exec } from 'child_process';
-import _fs from 'fs-extra';
 import { envMock, mockExecAll } from '../../../../test/execUtil';
 import { mocked } from '../../../../test/util';
 import * as _env from '../../../util/exec/env';
+import * as _fs from '../../../util/fs/proxies';
 import { PostUpdateConfig } from '../../common';
 import * as _pnpmHelper from './pnpm';
 
-jest.mock('fs-extra');
 jest.mock('child_process');
 jest.mock('../../../util/exec/env');
+jest.mock('../../../util/fs/proxies');
 jest.mock('./node-version');
 
 const exec: jest.Mock<typeof _exec> = _exec as any;
diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts
index 16bab073bbf36a4b9ef6d0d8dca9f2a69dbe0968..69825df15d783c3083c50f3a1cc8261e3a6bbb73 100644
--- a/lib/manager/npm/post-update/pnpm.ts
+++ b/lib/manager/npm/post-update/pnpm.ts
@@ -1,9 +1,9 @@
-import { readFile, remove } from 'fs-extra';
 import { validRange } from 'semver';
 import { quote } from 'shlex';
 import { join } from 'upath';
 import { logger } from '../../../logger';
 import { ExecOptions, exec } from '../../../util/exec';
+import { readFile, remove } from '../../../util/fs';
 import { PostUpdateConfig, Upgrade } from '../../common';
 import { getNodeConstraint } from './node-version';
 
diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts
index f845e894b30063dbc6b60bdb27c3cd930489f635..944a227b1d1c220e8fd0e8c1710cfa91ac2969b8 100644
--- a/lib/manager/npm/post-update/yarn.ts
+++ b/lib/manager/npm/post-update/yarn.ts
@@ -1,5 +1,4 @@
 import is from '@sindresorhus/is';
-import { readFile, remove } from 'fs-extra';
 import { validRange } from 'semver';
 import { quote } from 'shlex';
 import { join } from 'upath';
@@ -8,6 +7,7 @@ import { id as npmId } from '../../../datasource/npm';
 import { logger } from '../../../logger';
 import { ExternalHostError } from '../../../types/errors/external-host-error';
 import { ExecOptions, exec } from '../../../util/exec';
+import { readFile, remove } from '../../../util/fs';
 import { PostUpdateConfig, Upgrade } from '../../common';
 import { getNodeConstraint } from './node-version';
 
diff --git a/lib/manager/nuget/extract.ts b/lib/manager/nuget/extract.ts
index 0b0dc14c1f1f81301743e6598300fd5d011f98c5..a6c31c46f512fb2bd17027557cda80be4ba796ea 100644
--- a/lib/manager/nuget/extract.ts
+++ b/lib/manager/nuget/extract.ts
@@ -1,11 +1,11 @@
 import * as path from 'path';
 import findUp from 'find-up';
-import { readFile } from 'fs-extra';
 import { XmlDocument } from 'xmldoc';
 import * as datasourceNuget from '../../datasource/nuget';
 import { logger } from '../../logger';
 import { SkipReason } from '../../types';
 import { clone } from '../../util/clone';
+import { readFile } from '../../util/fs';
 import { get } from '../../versioning';
 import * as semverVersioning from '../../versioning/semver';
 import { ExtractConfig, PackageDependency, PackageFile } from '../common';
diff --git a/lib/util/fs/index.ts b/lib/util/fs/index.ts
index 7f08141177e57a6e402712a5f9baa9d843f738a4..a44b77c012ca0849b25a4958c1f45a01a44945df 100644
--- a/lib/util/fs/index.ts
+++ b/lib/util/fs/index.ts
@@ -3,6 +3,8 @@ import { join, parse } from 'upath';
 import { RenovateConfig } from '../../config/common';
 import { logger } from '../../logger';
 
+export * from './proxies';
+
 let localDir = '';
 let cacheDir = '';
 
diff --git a/lib/util/fs/proxies.ts b/lib/util/fs/proxies.ts
new file mode 100644
index 0000000000000000000000000000000000000000..946707f666a7fc3141ec58fd20cac7d818dcfee5
--- /dev/null
+++ b/lib/util/fs/proxies.ts
@@ -0,0 +1,72 @@
+import * as fs from 'fs-extra';
+import { MoveOptions, WriteFileOptions } from 'fs-extra';
+
+// istanbul ignore next
+export function stat(path: string | Buffer): Promise<fs.Stats> {
+  return fs.stat(path);
+}
+
+// istanbul ignore next
+export function chmod(
+  path: string | Buffer,
+  mode: string | number
+): Promise<void> {
+  return fs.chmod(path, mode);
+}
+
+export async function readFile(fileName: string): Promise<Buffer>;
+export async function readFile(
+  fileName: string,
+  encoding: 'utf8'
+): Promise<string>;
+export async function readFile(
+  fileName: string,
+  encoding?: string
+): Promise<string | Buffer> {
+  return fs.readFile(fileName, encoding);
+}
+
+// istanbul ignore next
+export async function writeFile(
+  fileName: string,
+  fileContent: string
+): Promise<void> {
+  return fs.writeFile(fileName, fileContent);
+}
+
+// istanbul ignore next
+export async function outputFile(
+  file: string,
+  data: any,
+  options?: WriteFileOptions | string
+): Promise<void> {
+  return fs.outputFile(file, data, options);
+}
+
+export async function remove(dir: string): Promise<void> {
+  return fs.remove(dir);
+}
+
+// istanbul ignore next
+export async function unlink(path: string | Buffer): Promise<void> {
+  return fs.unlink(path);
+}
+
+// istanbul ignore next
+export async function exists(path: string): Promise<boolean> {
+  return fs.pathExists(path);
+}
+
+// istanbul ignore next
+export async function pathExists(path: string): Promise<boolean> {
+  return fs.pathExists(path);
+}
+
+// istanbul ignore next
+export function move(
+  src: string,
+  dest: string,
+  options?: MoveOptions
+): Promise<void> {
+  return fs.move(src, dest, options);
+}
diff --git a/lib/workers/branch/lock-files/index.spec.ts b/lib/workers/branch/lock-files/index.spec.ts
index a04a1535975a56dd00e5ebc23af1b02e681adbee..9963de3e3f8f53b9ce8859373a402f475b3b4fe9 100644
--- a/lib/workers/branch/lock-files/index.spec.ts
+++ b/lib/workers/branch/lock-files/index.spec.ts
@@ -1,4 +1,3 @@
-import _fs from 'fs-extra';
 import { git, mocked } from '../../../../test/util';
 import { getConfig } from '../../../config/defaults';
 import { PostUpdateConfig } from '../../../manager/common';
@@ -7,6 +6,7 @@ import * as _lerna from '../../../manager/npm/post-update/lerna';
 import * as _npm from '../../../manager/npm/post-update/npm';
 import * as _pnpm from '../../../manager/npm/post-update/pnpm';
 import * as _yarn from '../../../manager/npm/post-update/yarn';
+import * as _fs from '../../../util/fs/proxies';
 import * as _hostRules from '../../../util/host-rules';
 
 const defaultConfig = getConfig();