Repository: JoshuaKGoldberg/create-typescript-app (ts)

Issue:
🚀 Feature: Support typescript-eslint@8.0
### Bug Report Checklist

- [X] I have pulled the latest `main` branch of the repository.
- [X] I have [searched for related issues](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aissue) and found none that matched my issue.

### Overview

`typescript-eslint@8` is stable now. Let's use it!

### Additional Info

💖 

Pull request:
feat: typescript-eslint@8
## PR Checklist

- [x] Addresses an existing open issue: fixes #1594 
- [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)
- [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CONTRIBUTING.md) were taken

## Overview

Also removes an unnecessary `"outDir": "lib"` from the `tsconfig.json`. It's a holdover from when `tsc` was used to compile to the `lib/` directory.

💖 

Patch:
diff --git a/eslint.config.js b/eslint.config.js
index b18ec6b..edc111e 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -55,10 +55,11 @@ export default tseslint.config(
 		files: ["**/*.js", "**/*.ts"],
 		languageOptions: {
 			parserOptions: {
-				EXPERIMENTAL_useProjectService: {
-					allowDefaultProjectForFiles: ["./*.*s", "eslint.config.js"],
+				projectService: {
+					allowDefaultProject: ["*.config.*s", "bin/*.js", "script/*.ts"],
 					defaultProject: "./tsconfig.json",
 				},
+				tsconfigRootDir: import.meta.dirname,
 			},
 		},
 		rules: {
diff --git a/package.json b/package.json
index 22bc508..df905cd 100644
--- a/package.json
+++ b/package.json
@@ -100,7 +100,7 @@
 		"tsup": "^8.1.0",
 		"tsx": "^4.9.0",
 		"typescript": "^5.5.2",
-		"typescript-eslint": "^7.7.0",
+		"typescript-eslint": "^8.0.0",
 		"vitest": "^2.0.2"
 	},
 	"engines": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 657c4a3..6f34374 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -181,8 +181,8 @@ importers:
         specifier: ^5.5.2
         version: 5.5.2
       typescript-eslint:
-        specifier: ^7.7.0
-        version: 7.7.0(eslint@9.2.0)(typescript@5.5.2)
+        specifier: ^8.0.0
+        version: 8.0.0(eslint@9.2.0)(typescript@5.5.2)
       vitest:
         specifier: ^2.0.2
         version: 2.0.2(@types/node@20.12.7)
@@ -1348,22 +1348,22 @@ packages:
   '@types/unist@2.0.6':
     resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
 
-  '@typescript-eslint/eslint-plugin@7.7.0':
-    resolution: {integrity: sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==}
-    engines: {node: ^18.18.0 || >=20.0.0}
+  '@typescript-eslint/eslint-plugin@8.0.0':
+    resolution: {integrity: sha512-STIZdwEQRXAHvNUS6ILDf5z3u95Gc8jzywunxSNqX00OooIemaaNIA0vEgynJlycL5AjabYLLrIyHd4iazyvtg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
-      '@typescript-eslint/parser': ^7.0.0
-      eslint: ^8.56.0
+      '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
+      eslint: ^8.57.0 || ^9.0.0
       typescript: '*'
     peerDependenciesMeta:
       typescript:
         optional: true
 
-  '@typescript-eslint/parser@7.7.0':
-    resolution: {integrity: sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==}
-    engines: {node: ^18.18.0 || >=20.0.0}
+  '@typescript-eslint/parser@8.0.0':
+    resolution: {integrity: sha512-pS1hdZ+vnrpDIxuFXYQpLTILglTjSYJ9MbetZctrUawogUsPdz31DIIRZ9+rab0LhYNTsk88w4fIzVheiTbWOQ==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
-      eslint: ^8.56.0
+      eslint: ^8.57.0 || ^9.0.0
       typescript: '*'
     peerDependenciesMeta:
       typescript:
@@ -1377,11 +1377,14 @@ packages:
     resolution: {integrity: sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==}
     engines: {node: ^18.18.0 || >=20.0.0}
 
-  '@typescript-eslint/type-utils@7.7.0':
-    resolution: {integrity: sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==}
-    engines: {node: ^18.18.0 || >=20.0.0}
+  '@typescript-eslint/scope-manager@8.0.0':
+    resolution: {integrity: sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@typescript-eslint/type-utils@8.0.0':
+    resolution: {integrity: sha512-mJAFP2mZLTBwAn5WI4PMakpywfWFH5nQZezUQdSKV23Pqo6o9iShQg1hP2+0hJJXP2LnZkWPphdIq4juYYwCeg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
-      eslint: ^8.56.0
       typescript: '*'
     peerDependenciesMeta:
       typescript:
@@ -1395,6 +1398,10 @@ packages:
     resolution: {integrity: sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==}
     engines: {node: ^18.18.0 || >=20.0.0}
 
+  '@typescript-eslint/types@8.0.0':
+    resolution: {integrity: sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   '@typescript-eslint/typescript-estree@6.21.0':
     resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==}
     engines: {node: ^16.0.0 || >=18.0.0}
@@ -1413,6 +1420,15 @@ packages:
       typescript:
         optional: true
 
+  '@typescript-eslint/typescript-estree@8.0.0':
+    resolution: {integrity: sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
   '@typescript-eslint/utils@6.21.0':
     resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==}
     engines: {node: ^16.0.0 || >=18.0.0}
@@ -1425,6 +1441,12 @@ packages:
     peerDependencies:
       eslint: ^8.56.0
 
+  '@typescript-eslint/utils@8.0.0':
+    resolution: {integrity: sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      eslint: ^8.57.0 || ^9.0.0
+
   '@typescript-eslint/visitor-keys@6.21.0':
     resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==}
     engines: {node: ^16.0.0 || >=18.0.0}
@@ -1433,6 +1455,10 @@ packages:
     resolution: {integrity: sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==}
     engines: {node: ^18.18.0 || >=20.0.0}
 
+  '@typescript-eslint/visitor-keys@8.0.0':
+    resolution: {integrity: sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   '@vitest/coverage-v8@2.0.2':
     resolution: {integrity: sha512-iA8eb4PMid3bMc++gfQSTvYE1QL//fC8pz+rKsTUDBFjdDiy/gH45hvpqyDu5K7FHhvgG0GNNCJzTMMSFKhoxg==}
     peerDependencies:
@@ -4280,11 +4306,10 @@ packages:
   typedarray@0.0.6:
     resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
 
-  typescript-eslint@7.7.0:
-    resolution: {integrity: sha512-wZZ+7mTQJCn4mGAvzdERtL4vwKGM/mF9cMSMeKUllz3Hgbd1Mdd5L60Q+nJmCio9RB4OyMMr0EX4Ry2Q7jiAyw==}
-    engines: {node: ^18.18.0 || >=20.0.0}
+  typescript-eslint@8.0.0:
+    resolution: {integrity: sha512-yQWBJutWL1PmpmDddIOl9/Mi6vZjqNCjqSGBMQ4vsc2Aiodk0SnbQQWPXbSy0HNuKCuGkw1+u4aQ2mO40TdhDQ==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
-      eslint: ^8.56.0
       typescript: '*'
     peerDependenciesMeta:
       typescript:
@@ -5576,32 +5601,30 @@ snapshots:
 
   '@types/unist@2.0.6': {}
 
-  '@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@9.2.0)(typescript@5.5.2))(eslint@9.2.0)(typescript@5.5.2)':
+  '@typescript-eslint/eslint-plugin@8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.2.0)(typescript@5.5.2))(eslint@9.2.0)(typescript@5.5.2)':
     dependencies:
       '@eslint-community/regexpp': 4.10.0
-      '@typescript-eslint/parser': 7.7.0(eslint@9.2.0)(typescript@5.5.2)
-      '@typescript-eslint/scope-manager': 7.7.0
-      '@typescript-eslint/type-utils': 7.7.0(eslint@9.2.0)(typescript@5.5.2)
-      '@typescript-eslint/utils': 7.7.0(eslint@9.2.0)(typescript@5.5.2)
-      '@typescript-eslint/visitor-keys': 7.7.0
-      debug: 4.3.5
+      '@typescript-eslint/parser': 8.0.0(eslint@9.2.0)(typescript@5.5.2)
+      '@typescript-eslint/scope-manager': 8.0.0
+      '@typescript-eslint/type-utils': 8.0.0(eslint@9.2.0)(typescript@5.5.2)
+      '@typescript-eslint/utils': 8.0.0(eslint@9.2.0)(typescript@5.5.2)
+      '@typescript-eslint/visitor-keys': 8.0.0
       eslint: 9.2.0
       graphemer: 1.4.0
       ignore: 5.3.1
       natural-compare: 1.4.0
-      semver: 7.6.2
       ts-api-utils: 1.3.0(typescript@5.5.2)
     optionalDependencies:
       typescript: 5.5.2
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/parser@7.7.0(eslint@9.2.0)(typescript@5.5.2)':
+  '@typescript-eslint/parser@8.0.0(eslint@9.2.0)(typescript@5.5.2)':
     dependencies:
-      '@typescript-eslint/scope-manager': 7.7.0
-      '@typescript-eslint/types': 7.7.0
-      '@typescript-eslint/typescript-estree': 7.7.0(typescript@5.5.2)
-      '@typescript-eslint/visitor-keys': 7.7.0
+      '@typescript-eslint/scope-manager': 8.0.0
+      '@typescript-eslint/types': 8.0.0
+      '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.5.2)
+      '@typescript-eslint/visitor-keys': 8.0.0
       debug: 4.3.5
       eslint: 9.2.0
     optionalDependencies:
@@ -5619,22 +5642,29 @@ snapshots:
       '@typescript-eslint/types': 7.7.0
       '@typescript-eslint/visitor-keys': 7.7.0
 
-  '@typescript-eslint/type-utils@7.7.0(eslint@9.2.0)(typescript@5.5.2)':
+  '@typescript-eslint/scope-manager@8.0.0':
     dependencies:
-      '@typescript-eslint/typescript-estree': 7.7.0(typescript@5.5.2)
-      '@typescript-eslint/utils': 7.7.0(eslint@9.2.0)(typescript@5.5.2)
+      '@typescript-eslint/types': 8.0.0
+      '@typescript-eslint/visitor-keys': 8.0.0
+
+  '@typescript-eslint/type-utils@8.0.0(eslint@9.2.0)(typescript@5.5.2)':
+    dependencies:
+      '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.5.2)
+      '@typescript-eslint/utils': 8.0.0(eslint@9.2.0)(typescript@5.5.2)
       debug: 4.3.5
-      eslint: 9.2.0
       ts-api-utils: 1.3.0(typescript@5.5.2)
     optionalDependencies:
       typescript: 5.5.2
     transitivePeerDependencies:
+      - eslint
       - supports-color
 
   '@typescript-eslint/types@6.21.0': {}
 
   '@typescript-eslint/types@7.7.0': {}
 
+  '@typescript-eslint/types@8.0.0': {}
+
   '@typescript-eslint/typescript-estree@6.21.0(typescript@5.5.2)':
     dependencies:
       '@typescript-eslint/types': 6.21.0
@@ -5665,6 +5695,21 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
+  '@typescript-eslint/typescript-estree@8.0.0(typescript@5.5.2)':
+    dependencies:
+      '@typescript-eslint/types': 8.0.0
+      '@typescript-eslint/visitor-keys': 8.0.0
+      debug: 4.3.5
+      globby: 11.1.0
+      is-glob: 4.0.3
+      minimatch: 9.0.5
+      semver: 7.6.2
+      ts-api-utils: 1.3.0(typescript@5.5.2)
+    optionalDependencies:
+      typescript: 5.5.2
+    transitivePeerDependencies:
+      - supports-color
+
   '@typescript-eslint/utils@6.21.0(eslint@9.2.0)(typescript@5.5.2)':
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0)
@@ -5693,6 +5738,17 @@ snapshots:
       - supports-color
       - typescript
 
+  '@typescript-eslint/utils@8.0.0(eslint@9.2.0)(typescript@5.5.2)':
+    dependencies:
+      '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0)
+      '@typescript-eslint/scope-manager': 8.0.0
+      '@typescript-eslint/types': 8.0.0
+      '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.5.2)
+      eslint: 9.2.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
   '@typescript-eslint/visitor-keys@6.21.0':
     dependencies:
       '@typescript-eslint/types': 6.21.0
@@ -5703,6 +5759,11 @@ snapshots:
       '@typescript-eslint/types': 7.7.0
       eslint-visitor-keys: 3.4.3
 
+  '@typescript-eslint/visitor-keys@8.0.0':
+    dependencies:
+      '@typescript-eslint/types': 8.0.0
+      eslint-visitor-keys: 3.4.3
+
   '@vitest/coverage-v8@2.0.2(vitest@2.0.2(@types/node@20.12.7))':
     dependencies:
       '@ampproject/remapping': 2.3.0
@@ -8937,15 +8998,15 @@ snapshots:
 
   typedarray@0.0.6: {}
 
-  typescript-eslint@7.7.0(eslint@9.2.0)(typescript@5.5.2):
+  typescript-eslint@8.0.0(eslint@9.2.0)(typescript@5.5.2):
     dependencies:
-      '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0(eslint@9.2.0)(typescript@5.5.2))(eslint@9.2.0)(typescript@5.5.2)
-      '@typescript-eslint/parser': 7.7.0(eslint@9.2.0)(typescript@5.5.2)
-      '@typescript-eslint/utils': 7.7.0(eslint@9.2.0)(typescript@5.5.2)
-      eslint: 9.2.0
+      '@typescript-eslint/eslint-plugin': 8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.2.0)(typescript@5.5.2))(eslint@9.2.0)(typescript@5.5.2)
+      '@typescript-eslint/parser': 8.0.0(eslint@9.2.0)(typescript@5.5.2)
+      '@typescript-eslint/utils': 8.0.0(eslint@9.2.0)(typescript@5.5.2)
     optionalDependencies:
       typescript: 5.5.2
     transitivePeerDependencies:
+      - eslint
       - supports-color
 
   typescript@5.5.2: {}
diff --git a/src/shared/options/createOptionDefaults/readDefaultsFromDevelopment.ts b/src/shared/options/createOptionDefaults/readDefaultsFromDevelopment.ts
index a682c96..f3c2403 100644
--- a/src/shared/options/createOptionDefaults/readDefaultsFromDevelopment.ts
+++ b/src/shared/options/createOptionDefaults/readDefaultsFromDevelopment.ts
@@ -8,8 +8,8 @@ export function readDefaultsFromDevelopment() {
 	);
 
 	const guideTag = lazyValue(async () =>
-		(await development()).match(
-			/> .*guided walkthrough, see \[((?!\[).+)\]\((.+)\)/i,
+		/> .*guided walkthrough, see \[((?!\[).+)\]\((.+)\)/i.exec(
+			await development(),
 		),
 	);
 
diff --git a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts b/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
index 2b8c891..1a89c5d 100644
--- a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
+++ b/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
@@ -6,7 +6,7 @@ export function readDefaultsFromReadme() {
 	const readme = lazyValue(async () => await readFileSafe("README.md", ""));
 
 	const imageTag = lazyValue(
-		async () => (await readme()).match(/<img.+src.+\/>/)?.[0],
+		async () => /<img.+src.+\/>/.exec(await readme())?.[0],
 	);
 
 	return {
@@ -15,8 +15,8 @@ export function readDefaultsFromReadme() {
 				?.match(/src\s*=(.+)?\/>/)?.[1]
 				?.replaceAll(/^['"]|['"]$/g, ""),
 		title: async () =>
-			(await readme())
-				.match(/^(?:# |<h1\s+align="center">)(.*?)(?:<\/h1>)?$/i)?.[1]
+			/^(?:# |<h1\s+align="center">)(.*?)(?:<\/h1>)?$/i
+				.exec(await readme())?.[1]
 				?.trim()
 				.replace(/<[^>]+(?:>|$)/g, ""),
 	};
diff --git a/src/steps/writing/creation/createESLintConfig.ts b/src/steps/writing/creation/createESLintConfig.ts
index 1814988..538e73e 100644
--- a/src/steps/writing/creation/createESLintConfig.ts
+++ b/src/steps/writing/creation/createESLintConfig.ts
@@ -73,10 +73,11 @@ export default tseslint.config(
 		files: ["**/*.js", "**/*.ts"],
 		languageOptions: {
 			parserOptions: {
-				EXPERIMENTAL_useProjectService: {
-					allowDefaultProjectForFiles: ["./*.*s", "eslint.config.js"],
+				projectService: {
+					allowDefaultProject: ["*.*s", "eslint.config.js"],
 					defaultProject: "./tsconfig.json",
 				},
+				tsconfigRootDir: import.meta.dirname
 			},
 		},
 		rules: {
diff --git a/src/steps/writing/creation/rootFiles.ts b/src/steps/writing/creation/rootFiles.ts
index 36ab969..c5ea67e 100644
--- a/src/steps/writing/creation/rootFiles.ts
+++ b/src/steps/writing/creation/rootFiles.ts
@@ -124,7 +124,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 				module: "NodeNext",
 				moduleResolution: "NodeNext",
 				noEmit: true,
-				outDir: "lib",
 				resolveJsonModule: true,
 				skipLibCheck: true,
 				sourceMap: true,
diff --git a/tsconfig.json b/tsconfig.json
index f0eaf1a..223cce1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -6,7 +6,6 @@
 		"module": "NodeNext",
 		"moduleResolution": "NodeNext",
 		"noEmit": true,
-		"outDir": "lib",
 		"resolveJsonModule": true,
 		"skipLibCheck": true,
 		"sourceMap": true,


Test patch:
diff --git a/script/__snapshots__/migrate-test-e2e.ts.snap b/script/__snapshots__/migrate-test-e2e.ts.snap
index 37f5a1c..5387c7b 100644
--- a/script/__snapshots__/migrate-test-e2e.ts.snap
+++ b/script/__snapshots__/migrate-test-e2e.ts.snap
@@ -116,6 +116,15 @@ exports[`expected file changes > eslint.config.js 1`] = `
  import eslint from "@eslint/js";
  import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
  import jsdoc from "eslint-plugin-jsdoc";
+@@ ... @@ export default tseslint.config(
+ 		languageOptions: {
+ 			parserOptions: {
+ 				projectService: {
+-					allowDefaultProject: ["*.config.*s", "bin/*.js", "script/*.ts"],
++					allowDefaultProject: ["*.*s", "eslint.config.js"],
+ 					defaultProject: "./tsconfig.json",
+ 				},
+ 				tsconfigRootDir: import.meta.dirname,
 @@ ... @@ export default tseslint.config(
  			"no-constant-condition": "off",
  
diff --git a/script/migrate-test-e2e.ts b/script/migrate-test-e2e.ts
index 0e19838..01830d9 100644
--- a/script/migrate-test-e2e.ts
+++ b/script/migrate-test-e2e.ts
@@ -74,12 +74,12 @@ await fs.writeFile(
 		.replace(
 			/All Contributors: \d+/g,
 			// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-			originalReadme.match(/All Contributors: \d+/)![0],
+			/All Contributors: \d+/.exec(originalReadme)![0],
 		)
 		.replace(
 			/all_contributors-\d+/g,
 			// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-			originalReadme.match(/all_contributors-\d+/)![0],
+			/all_contributors-\d+/.exec(originalReadme)![0],
 		),
 );
 
@@ -90,12 +90,12 @@ await fs.writeFile(
 		.replace(
 			/All Contributors: \d+/g,
 			// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-			originalReadme.match(/All Contributors: \d+/)![0],
+			/All Contributors: \d+/.exec(originalReadme)![0],
 		)
 		.replace(
 			/all_contributors-\d+/g,
 			// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-			originalReadme.match(/all_contributors-\d+/)![0],
+			/all_contributors-\d+/.exec(originalReadme)![0],
 		),
 );
 
diff --git a/src/steps/writing/creation/createESLintConfig.test.ts b/src/steps/writing/creation/createESLintConfig.test.ts
index cc498f5..72df5f1 100644
--- a/src/steps/writing/creation/createESLintConfig.test.ts
+++ b/src/steps/writing/creation/createESLintConfig.test.ts
@@ -70,10 +70,11 @@ describe("createESLintConfig", () => {
 				    files: ["**/*.js", "**/*.ts"],
 				    languageOptions: {
 				      parserOptions: {
-				        EXPERIMENTAL_useProjectService: {
-				          allowDefaultProjectForFiles: ["./*.*s", "eslint.config.js"],
+				        projectService: {
+				          allowDefaultProject: ["*.*s", "eslint.config.js"],
 				          defaultProject: "./tsconfig.json",
 				        },
+				        tsconfigRootDir: import.meta.dirname,
 				      },
 				    },
 				    rules: {
@@ -154,10 +155,11 @@ describe("createESLintConfig", () => {
 				    files: ["**/*.js", "**/*.ts"],
 				    languageOptions: {
 				      parserOptions: {
-				        EXPERIMENTAL_useProjectService: {
-				          allowDefaultProjectForFiles: ["./*.*s", "eslint.config.js"],
+				        projectService: {
+				          allowDefaultProject: ["*.*s", "eslint.config.js"],
 				          defaultProject: "./tsconfig.json",
 				        },
+				        tsconfigRootDir: import.meta.dirname,
 				      },
 				    },
 				    rules: {