diff --git a/lib/modules/manager/api.ts b/lib/modules/manager/api.ts
index e450e35e3de13f213bb161d9dc11a042721a9664..e01c0fecf3fc10dee12af3f482383b433aa54846 100644
--- a/lib/modules/manager/api.ts
+++ b/lib/modules/manager/api.ts
@@ -40,6 +40,7 @@ import * as homebrew from './homebrew';
 import * as html from './html';
 import * as jenkins from './jenkins';
 import * as jsonnetBundler from './jsonnet-bundler';
+import * as kotlinScript from './kotlin-script';
 import * as kubernetes from './kubernetes';
 import * as kustomize from './kustomize';
 import * as leiningen from './leiningen';
@@ -117,6 +118,7 @@ api.set('homebrew', homebrew);
 api.set('html', html);
 api.set('jenkins', jenkins);
 api.set('jsonnet-bundler', jsonnetBundler);
+api.set('kotlin-script', kotlinScript);
 api.set('kubernetes', kubernetes);
 api.set('kustomize', kustomize);
 api.set('leiningen', leiningen);
diff --git a/lib/modules/manager/kotlin-script/__fixtures__/custom-repositories.main.kts b/lib/modules/manager/kotlin-script/__fixtures__/custom-repositories.main.kts
new file mode 100644
index 0000000000000000000000000000000000000000..b945d7af11ff3f229c2f31eef7728f1b0c4cfccf
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/__fixtures__/custom-repositories.main.kts
@@ -0,0 +1,10 @@
+#!/usr/bin/env kotlin
+@file:Repository("https://jitpack.io")
+@file:DependsOn("it.krzeminski:github-actions-kotlin-dsl:0.22.0")
+@file:DependsOn("org.eclipse.jgit:org.eclipse.jgit:4.6.0.201612231935-r")
+@file:Repository("https://some.other.repo/foo/bar/baz")
+@file:Repository("")
+
+// ...
+
+println("Hello world")
diff --git a/lib/modules/manager/kotlin-script/__fixtures__/generic-case.main.kts b/lib/modules/manager/kotlin-script/__fixtures__/generic-case.main.kts
new file mode 100644
index 0000000000000000000000000000000000000000..07671b56b683551bf9f59e59fac250043721a3c0
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/__fixtures__/generic-case.main.kts
@@ -0,0 +1,15 @@
+#!/usr/bin/env kotlin
+@file:DependsOn("it.krzeminski:github-actions-kotlin-dsl:0.22.0")
+@file:DependsOn(
+  "org.eclipse.jgit:org.eclipse.jgit:4.6.0.201612231935-r"
+)
+
+@file : DependsOn
+  (
+  "org.jetbrains.lets-plot:lets-plot-kotlin-jvm:3.0.2"
+
+)
+
+// ...
+
+println("Hello world")
diff --git a/lib/modules/manager/kotlin-script/__fixtures__/missing-parts.main.kts b/lib/modules/manager/kotlin-script/__fixtures__/missing-parts.main.kts
new file mode 100644
index 0000000000000000000000000000000000000000..71a5f05fad7ad52c7c6c87b9bf4cab1e5cf8f5b9
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/__fixtures__/missing-parts.main.kts
@@ -0,0 +1,9 @@
+#!/usr/bin/env kotlin
+@file:DependsOn("it.krzeminski:github-actions-kotlin-dsl:0.22.0")
+@file:DependsOn(":org.eclipse.jgit:4.6.0.201612231935-r")
+@file:DependsOn("org.jetbrains.lets-plot::3.0.2")
+@file:DependsOn("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:")
+
+// ...
+
+println("Hello world")
diff --git a/lib/modules/manager/kotlin-script/extract.spec.ts b/lib/modules/manager/kotlin-script/extract.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9272c601065416684369886b29fe3b7e4ae49483
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/extract.spec.ts
@@ -0,0 +1,98 @@
+import { Fixtures } from '../../../../test/fixtures';
+import { extractPackageFile } from '.';
+
+const genericCaseFileContent = Fixtures.get('generic-case.main.kts');
+const customRepositoriesFileContent = Fixtures.get(
+  'custom-repositories.main.kts'
+);
+const missingPartsFileContent = Fixtures.get('missing-parts.main.kts');
+
+describe('modules/manager/kotlin-script/extract', () => {
+  describe('extractPackageFile()', () => {
+    it('extracts dependencies in a generic case', () => {
+      // when
+      const packageFile = extractPackageFile(genericCaseFileContent);
+
+      // then
+      expect(packageFile).toEqual({
+        deps: [
+          {
+            depName: 'it.krzeminski:github-actions-kotlin-dsl',
+            currentValue: '0.22.0',
+            replaceString: '"it.krzeminski:github-actions-kotlin-dsl:0.22.0"',
+            datasource: 'maven',
+          },
+          {
+            depName: 'org.eclipse.jgit:org.eclipse.jgit',
+            currentValue: '4.6.0.201612231935-r',
+            replaceString:
+              '"org.eclipse.jgit:org.eclipse.jgit:4.6.0.201612231935-r"',
+            datasource: 'maven',
+          },
+          {
+            depName: 'org.jetbrains.lets-plot:lets-plot-kotlin-jvm',
+            currentValue: '3.0.2',
+            replaceString:
+              '"org.jetbrains.lets-plot:lets-plot-kotlin-jvm:3.0.2"',
+            datasource: 'maven',
+          },
+        ],
+      });
+    });
+
+    it('detects custom repository definitions', () => {
+      // when
+      const packageFile = extractPackageFile(customRepositoriesFileContent);
+
+      // then
+      expect(packageFile).toEqual({
+        deps: [
+          {
+            depName: 'it.krzeminski:github-actions-kotlin-dsl',
+            currentValue: '0.22.0',
+            replaceString: '"it.krzeminski:github-actions-kotlin-dsl:0.22.0"',
+            datasource: 'maven',
+          },
+          {
+            depName: 'org.eclipse.jgit:org.eclipse.jgit',
+            currentValue: '4.6.0.201612231935-r',
+            replaceString:
+              '"org.eclipse.jgit:org.eclipse.jgit:4.6.0.201612231935-r"',
+            datasource: 'maven',
+          },
+        ],
+        registryUrls: [
+          'https://jitpack.io',
+          'https://some.other.repo/foo/bar/baz',
+        ],
+      });
+    });
+
+    it('no dependencies', () => {
+      // when
+      const packageFile = extractPackageFile(`
+        #!/usr/bin/env kotlin
+        println("Hello world")`);
+
+      // then
+      expect(packageFile).toBeNull();
+    });
+
+    it('skips dependencies with missing parts', () => {
+      // when
+      const packageFile = extractPackageFile(missingPartsFileContent);
+
+      // then
+      expect(packageFile).toEqual({
+        deps: [
+          {
+            depName: 'it.krzeminski:github-actions-kotlin-dsl',
+            currentValue: '0.22.0',
+            replaceString: '"it.krzeminski:github-actions-kotlin-dsl:0.22.0"',
+            datasource: 'maven',
+          },
+        ],
+      });
+    });
+  });
+});
diff --git a/lib/modules/manager/kotlin-script/extract.ts b/lib/modules/manager/kotlin-script/extract.ts
new file mode 100644
index 0000000000000000000000000000000000000000..62125c3c3f8ccfa559484a6261c2c579403647a5
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/extract.ts
@@ -0,0 +1,40 @@
+import is from '@sindresorhus/is';
+import { regEx } from '../../../util/regex';
+import { MavenDatasource } from '../../datasource/maven';
+import type { PackageDependency, PackageFile } from '../types';
+
+const dependsOnRegex = regEx(
+  /@file\s*:\s*DependsOn\s*\(\s*(?<replaceString>"(?<groupId>.+):(?<artifactId>.+):(?<version>.+)")\s*\)/g
+);
+const repositoryRegex = regEx(
+  /@file\s*:\s*Repository\s*\(\s*"(?<repositoryName>.+)"\s*\)/g
+);
+
+export function extractPackageFile(fileContent: string): PackageFile | null {
+  const registryUrls: string[] = [...fileContent.matchAll(repositoryRegex)]
+    .map((match) => match.groups?.repositoryName)
+    .filter(is.string);
+
+  const matches = [...fileContent.matchAll(dependsOnRegex)]
+    .map((m) => m.groups)
+    .filter(is.truthy);
+  const deps: PackageDependency[] = [];
+  for (const match of matches) {
+    const dep: PackageDependency = {
+      currentValue: match.version,
+      depName: `${match.groupId}:${match.artifactId}`,
+      replaceString: match.replaceString,
+      datasource: MavenDatasource.id,
+    };
+    deps.push(dep);
+  }
+
+  if (deps.length === 0) {
+    return null;
+  }
+
+  return {
+    deps,
+    ...(registryUrls.length && { registryUrls }),
+  };
+}
diff --git a/lib/modules/manager/kotlin-script/index.spec.ts b/lib/modules/manager/kotlin-script/index.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c2d04adaa30d3311357596824b3dfae24a1aefc1
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/index.spec.ts
@@ -0,0 +1,11 @@
+import { regEx } from '../../../util/regex';
+import { defaultConfig } from '.';
+
+describe('modules/manager/kotlin-script/index', () => {
+  it('fileMatch regex is correct', () => {
+    expect(defaultConfig.fileMatch).toHaveLength(1);
+    defaultConfig.fileMatch.forEach((pattern) => {
+      expect(() => regEx(pattern)).not.toThrow();
+    });
+  });
+});
diff --git a/lib/modules/manager/kotlin-script/index.ts b/lib/modules/manager/kotlin-script/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dbded231b6b2969c835da3361f5d17252fc1b04a
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/index.ts
@@ -0,0 +1,9 @@
+import { MavenDatasource } from '../../datasource/maven';
+
+export { extractPackageFile } from './extract';
+
+export const defaultConfig = {
+  fileMatch: ['^.+\\.main\\.kts$'],
+};
+
+export const supportedDatasources = [MavenDatasource.id];
diff --git a/lib/modules/manager/kotlin-script/readme.md b/lib/modules/manager/kotlin-script/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..e227cd5a830346fcc599cd7a681761fd25666062
--- /dev/null
+++ b/lib/modules/manager/kotlin-script/readme.md
@@ -0,0 +1,32 @@
+---
+title: Kotlin Script dependency versions
+description: Kotlin Script dependency versions support in Renovate
+---
+
+Renovate supports upgrading dependencies in [Kotlin Script](https://github.com/Kotlin/KEEP/blob/master/proposals/scripting-support.md) files.
+These are self-contained scripts where one can write Kotlin code with JVM backend, and compilation happens when the
+scripts are ran. For example:
+
+```kotlin
+#!/usr/bin/env kotlin
+@file:Repository("https://jitpack.io")
+@file:DependsOn("com.github.krzema12:github-actions-kotlin-dsl:main-SNAPSHOT")
+@file:DependsOn("org.eclipse.jgit:org.eclipse.jgit:4.6.0.201612231935-r")
+@file:DependsOn("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:3.0.2")
+
+println("Hello world!")
+
+// ...
+```
+
+By default, Renovate scans files only with `.main.kts` extension and not `.kts`, to avoid ambiguity with Gradle config
+files that have `.gradle.kts` extension. As there are cases where just `.kts` extension or no extension is used,
+Renovate can be [configured](https://docs.renovatebot.com/configuration-options/) to scan also these:
+
+```json
+{
+  "kotlin-script": {
+    "fileMatch": ["^.*\\.kts$"]
+  }
+}
+```