diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md
index 339805bbc3693f79e4409c9c3d6866d1d9d7defb..279077a95f833397ef88d4959456afaf07de23ca 100644
--- a/docs/usage/self-hosted-configuration.md
+++ b/docs/usage/self-hosted-configuration.md
@@ -487,3 +487,13 @@ This is currently applicable to `npm` and `lerna`/`npm` only, and only used in c
 ## username
 
 Mandatory if a GitHub app token is in use using the CLI.
+
+## writeDiscoveredRepos
+
+Optional parameter which allows to write the discovered repositories into a JSON file instead of renovating them.
+
+Usage: `renovate --write-discovered-repos=/tmp/renovate-repos.json`
+
+```json
+["myOrg/myRepo", "myOrg/anotherRepo"]
+```
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index 622c0439077de4088b4ddfd1214447b8a43d6539..7a757b04d8cec1f986b72716fdf8e05e0cabf8a3 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -2051,6 +2051,13 @@ const options: RenovateOptions[] = [
     stage: 'repository',
     globalOnly: true,
   },
+  {
+    name: 'writeDiscoveredRepos',
+    description: 'Writes discovered repositories to a JSON file and then exit.',
+    type: 'string',
+    globalOnly: true,
+    env: false,
+  },
 ];
 
 export function getOptions(): RenovateOptions[] {
diff --git a/lib/workers/global/index.spec.ts b/lib/workers/global/index.spec.ts
index 988d2b352e10816051e5bf13e0a7cdc83d1fd772..13d93bcba47971b61c51e666f46a713a8c0b26fb 100644
--- a/lib/workers/global/index.spec.ts
+++ b/lib/workers/global/index.spec.ts
@@ -1,5 +1,6 @@
+import { expect } from '@jest/globals';
 import { ERROR, WARN } from 'bunyan';
-import { logger } from '../../../test/util';
+import { fs, logger } from '../../../test/util';
 import {
   PLATFORM_TYPE_GITHUB,
   PLATFORM_TYPE_GITLAB,
@@ -12,6 +13,7 @@ import * as _limits from './limits';
 import * as globalWorker from '.';
 
 jest.mock('../repository');
+jest.mock('../../util/fs');
 
 // imports are readonly
 const repositoryWorker = _repositoryWorker;
@@ -130,4 +132,25 @@ describe('workers/global/index', () => {
       expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(1);
     });
   });
+
+  describe('write repositories to file', () => {
+    it('successfully write file', async () => {
+      configParser.parseConfigs.mockResolvedValueOnce({
+        repositories: ['myOrg/myRepo'],
+        platform: PLATFORM_TYPE_GITHUB,
+        endpoint: 'https://github.com/',
+        writeDiscoveredRepos: '/tmp/renovate-output.json',
+      });
+      fs.writeFile.mockReturnValueOnce(null);
+
+      expect(await globalWorker.start()).toEqual(0);
+      expect(fs.writeFile).toHaveBeenCalledTimes(1);
+      expect(fs.writeFile).toHaveBeenCalledWith(
+        '/tmp/renovate-output.json',
+        '["myOrg/myRepo"]'
+      );
+      expect(configParser.parseConfigs).toHaveBeenCalledTimes(1);
+      expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(0);
+    });
+  });
 });
diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts
index d683f318669cb75bc7fd7f59bb1d8fc671936d5a..2c51a573d4b5b13a4ae594ee8ab9226fb4857f66 100644
--- a/lib/workers/global/index.ts
+++ b/lib/workers/global/index.ts
@@ -14,6 +14,7 @@ import type {
 } from '../../config/types';
 import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages';
 import { getProblems, logger, setMeta } from '../../logger';
+import { writeFile } from '../../util/fs';
 import * as hostRules from '../../util/host-rules';
 import * as repositoryWorker from '../repository';
 import { autodiscoverRepositories } from './autodiscover';
@@ -97,6 +98,16 @@ export async function start(): Promise<number> {
 
     // autodiscover repositories (needs to come after platform initialization)
     config = await autodiscoverRepositories(config);
+
+    if (is.nonEmptyString(config.writeDiscoveredRepos)) {
+      const content = JSON.stringify(config.repositories);
+      await writeFile(config.writeDiscoveredRepos, content);
+      logger.info(
+        `Written discovered repositories to ${config.writeDiscoveredRepos}`
+      );
+      return 0;
+    }
+
     // Iterate through repositories sequentially
     for (const repository of config.repositories) {
       if (haveReachedLimits()) {