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

Issue:
🐛 Bug: eslint.config.js used with ESM even if package type is `"commonjs"`
### Bug Report Checklist

- [x] I have tried restarting my IDE and the issue persists.
- [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.

### Expected

If a repo defines `"type": "commonjs"` in its `package.json`, then the ESLint config should either be `eslint.config.mjs` or use CJS.

### Actual

It's still printed as `eslint.config.js` with ESM.

### Additional Info

Example: https://github.com/JoshuaKGoldberg/package-json-validator/pull/178/files#r2025645674

Pull request description:
feat: add options.type
## PR Checklist

- [x] Addresses an existing open issue: fixes #2111
- [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

Goes a different, more comprehensive direction than #2110. Instead of encouraging a `blockPackageJson` it promotes `type` to a top-level option. `--type commonjs` will now work if a user really wants.

`blockESLint` will now print its config as `eslint.config.mjs` if `options.type` is `"commonjs"`. It's still `eslint.config.js` otherwise.

🎁 

Patch:
diff --git a/docs/CLI.md b/docs/CLI.md
index 160e192..cff2b6c 100644
--- a/docs/CLI.md
+++ b/docs/CLI.md
@@ -56,6 +56,7 @@ Each defaults to a value based on the running system, including an repository if
 | `--pnpm`       | `string`   | pnpm version for `package.json`'s `packageManager` field                                                            | Existing value in `package.json` if it exists                                                  |
 | `--repository` | `string`   | Name for the new repository                                                                                         | The same as `--directory`                                                                      |
 | `--title`      | `string`   | 'Title Case' title for the repository                                                                               | Title-cased `repository`                                                                       |
+| `--type`       | `string`   | package.json modules type                                                                                           | Existing value in `package.json` if it exists, or `"module"`                                   |
 | `--version`    | `string`   | package version to publish as and store in `package.json`                                                           | Existing value in `package.json` if it exists, or `"0.0.0"`                                    |
 | `--words`      | `string[]` | additional words to add to the CSpell dictionary                                                                    | Existing `words` in a `cspell.json` file if it exists, and any new words in from other options |
 
diff --git a/eslint.config.js b/eslint.config.js
index 6f9a572..7b87e41 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -42,7 +42,7 @@ export default tseslint.config(
 			tseslint.configs.strictTypeChecked,
 			tseslint.configs.stylisticTypeChecked,
 		],
-		files: ["**/*.js", "**/*.ts"],
+		files: ["**/*.{js,ts}"],
 		languageOptions: {
 			parserOptions: {
 				projectService: {
diff --git a/src/base.ts b/src/base.ts
index 0ee3395..6d761b0 100644
--- a/src/base.ts
+++ b/src/base.ts
@@ -155,6 +155,10 @@ export const base = createBase({
 			.optional()
 			.describe("GitHub branch ruleset ID for main branch protections"),
 		title: z.string().describe("'Title Case' title for the repository"),
+		type: z
+			.union([z.literal("commonjs"), z.literal("module")])
+			.optional()
+			.describe("package.json modules type"),
 		version: z
 			.string()
 			.optional()
@@ -294,6 +298,8 @@ export const base = createBase({
 			async () => await readTitle(getReadme, getRepository),
 		);
 
+		const getType = lazyValue(async () => (await getPackageData()).type);
+
 		const getVersion = lazyValue(async () => (await getPackageData()).version);
 
 		const getWords = lazyValue(async () => await readWords(take));
@@ -324,6 +330,7 @@ export const base = createBase({
 			repository: getRepository,
 			rulesetId: getRulesetId,
 			title: getTitle,
+			type: getType,
 			version: getVersion,
 			words: getWords,
 			workflowsVersions: getWorkflowData,
diff --git a/src/blocks/blockESLint.ts b/src/blocks/blockESLint.ts
index 020623c..757c924 100644
--- a/src/blocks/blockESLint.ts
+++ b/src/blocks/blockESLint.ts
@@ -71,6 +71,11 @@ export const blockESLint = base.createBlock({
 		const { explanations, extensions, ignores, imports, rules, settings } =
 			addons;
 
+		const [configFileName, fileExtensions] =
+			options.type === "commonjs"
+				? ["eslint.config.mjs", "js,mjs,ts"]
+				: ["eslint.config.js", "js,ts"];
+
 		const explanation =
 			explanations.length > 0
 				? `${explanations
@@ -99,7 +104,7 @@ export const blockESLint = base.createBlock({
 					"tseslint.configs.strictTypeChecked",
 					"tseslint.configs.stylisticTypeChecked",
 				],
-				files: ["**/*.js", "**/*.ts"],
+				files: [`**/*.{${fileExtensions}}`],
 				languageOptions: {
 					parserOptions: {
 						projectService: {
@@ -122,6 +127,14 @@ export const blockESLint = base.createBlock({
 				...(rules && { rules }),
 				...(settings && { settings }),
 			}),
+			...(options.type === "commonjs"
+				? [
+						printExtension({
+							files: ["*.mjs"],
+							languageOptions: { sourceType: "module" },
+						}),
+					]
+				: []),
 			...extensions.map((extension) =>
 				typeof extension === "string" ? extension : printExtension(extension),
 			),
@@ -207,7 +220,7 @@ Each should be shown in VS Code, and can be run manually on the command-line:
 				}),
 			],
 			files: {
-				"eslint.config.js": `${explanation}${importLines.join("\n")}
+				[configFileName]: `${explanation}${importLines.join("\n")}
 
 export default tseslint.config(
 	{ ignores: [${ignoreLines.join(", ")}] },
@@ -226,7 +239,7 @@ export default tseslint.config(
 			],
 		};
 	},
-	transition() {
+	transition({ options }) {
 		return {
 			addons: [
 				blockRemoveDependencies({
@@ -242,7 +255,13 @@ export default tseslint.config(
 					],
 				}),
 				blockRemoveFiles({
-					files: [".eslintrc*", ".eslintignore", "eslint.config.{cjs,mjs}"],
+					files: [
+						".eslintrc*",
+						".eslintignore",
+						options.type === "commonjs"
+							? "eslint.config.{cjs,js}"
+							: "eslint.config.{cjs,mjs}",
+					],
 				}),
 				blockRemoveWorkflows({
 					workflows: ["eslint", "lint"],
diff --git a/src/blocks/blockPackageJson.ts b/src/blocks/blockPackageJson.ts
index 72c49ad..637aba1 100644
--- a/src/blocks/blockPackageJson.ts
+++ b/src/blocks/blockPackageJson.ts
@@ -42,7 +42,6 @@ export const blockPackageJson = base.createBlock({
 				"package.json": sortPackageJson(
 					JSON.stringify(
 						removeUndefinedObjects({
-							type: "module",
 							...options.packageData,
 							...addons.properties,
 							author: { email: options.email.npm, name: options.author },
@@ -76,6 +75,7 @@ export const blockPackageJson = base.createBlock({
 								...options.packageData?.scripts,
 								...addons.properties.scripts,
 							},
+							type: options.type ?? "module",
 							version: options.version ?? "0.0.0",
 						}),
 					),
diff --git a/src/types.ts b/src/types.ts
index ea0349e..0483a84 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -24,6 +24,7 @@ export interface PartialPackageData {
 	publishConfig?: PartialPublishConfig;
 	repository?: string | { type: string; url: string };
 	scripts?: Record<string, string>;
+	type?: "commonjs" | "module";
 	version?: string;
 }
 


Test patch:
diff --git a/src/base.test.ts b/src/base.test.ts
index 45cf284..4b092a8 100644
--- a/src/base.test.ts
+++ b/src/base.test.ts
@@ -57,6 +57,7 @@ describe("base", () => {
 			pnpm: expect.any(String),
 			repository: "create-typescript-app",
 			title: "Create TypeScript App",
+			type: expect.any(String),
 			version: expect.any(String),
 			// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-require-imports
 			words: require("../cspell.json").words,
diff --git a/src/blocks/blockESLint.test.ts b/src/blocks/blockESLint.test.ts
index 35dd6f2..56d277d 100644
--- a/src/blocks/blockESLint.test.ts
+++ b/src/blocks/blockESLint.test.ts
@@ -110,7 +110,7 @@ describe("blockESLint", () => {
 				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
 				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
 				eslint.configs.recommended,
-				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.js", "**/*.ts"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, }
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, }
 			);",
 			  },
 			  "scripts": [
@@ -265,7 +265,165 @@ describe("blockESLint", () => {
 				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
 				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
 				eslint.configs.recommended,
-				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.js", "**/*.ts"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, }
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, }
+			);",
+			  },
+			  "scripts": [
+			    {
+			      "commands": [
+			        "pnpm lint --fix",
+			      ],
+			      "phase": 3,
+			    },
+			  ],
+			}
+		`);
+	});
+
+	test("transition mode with options.type set to commonjs", () => {
+		const creation = testBlock(blockESLint, {
+			mode: "transition",
+			options: {
+				...optionsBase,
+				type: "commonjs",
+			},
+		});
+
+		expect(creation).toMatchInlineSnapshot(`
+			{
+			  "addons": [
+			    {
+			      "addons": {
+			        "sections": {
+			          "Linting": {
+			            "contents": {
+			              "after": [
+			                "
+			For example, ESLint can be run with \`--fix\` to auto-fix some lint rule complaints:
+
+			\`\`\`shell
+			pnpm run lint --fix
+			\`\`\`
+			",
+			              ],
+			              "before": "
+			This package includes several forms of linting to enforce consistent code quality and styling.
+			Each should be shown in VS Code, and can be run manually on the command-line:
+			",
+			              "items": [
+			                "- \`pnpm lint\` ([ESLint](https://eslint.org) with [typescript-eslint](https://typescript-eslint.io)): Lints JavaScript and TypeScript source files",
+			              ],
+			              "plural": "Read the individual documentation for each linter to understand how it can be configured and used best.",
+			            },
+			          },
+			        },
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "jobs": [
+			          {
+			            "name": "Lint",
+			            "steps": [
+			              {
+			                "run": "pnpm lint",
+			              },
+			            ],
+			          },
+			        ],
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "properties": {
+			          "devDependencies": {
+			            "@eslint/js": "9.22.0",
+			            "@types/node": "22.13.10",
+			            "eslint": "9.22.0",
+			            "typescript-eslint": "8.26.1",
+			          },
+			          "scripts": {
+			            "lint": "eslint . --max-warnings 0",
+			          },
+			        },
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "extensions": [
+			          "dbaeumer.vscode-eslint",
+			        ],
+			        "settings": {
+			          "editor.codeActionsOnSave": {
+			            "source.fixAll.eslint": "explicit",
+			          },
+			          "eslint.probe": [
+			            "javascript",
+			            "javascriptreact",
+			            "json",
+			            "jsonc",
+			            "markdown",
+			            "typescript",
+			            "typescriptreact",
+			            "yaml",
+			          ],
+			          "eslint.rules.customizations": [
+			            {
+			              "rule": "*",
+			              "severity": "warn",
+			            },
+			          ],
+			        },
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "dependencies": [
+			          "@types/eslint",
+			          "@typescript-eslint/eslint-plugin",
+			          "@typescript-eslint/parser",
+			          "eslint-plugin-deprecation",
+			          "eslint-plugin-eslint-comments",
+			          "eslint-plugin-no-only-tests",
+			          "jsonc-eslint-parser",
+			          "yaml-eslint-parser",
+			        ],
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "files": [
+			          ".eslintrc*",
+			          ".eslintignore",
+			          "eslint.config.{cjs,js}",
+			        ],
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "workflows": [
+			          "eslint",
+			          "lint",
+			        ],
+			      },
+			      "block": [Function],
+			    },
+			  ],
+			  "files": {
+			    "eslint.config.mjs": "import eslint from "@eslint/js";
+			import tseslint from "typescript-eslint";
+
+			export default tseslint.config(
+				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
+				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
+				eslint.configs.recommended,
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,mjs,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, },{ files: ["*.mjs"], languageOptions: {"sourceType":"module"}, }
 			);",
 			  },
 			  "scripts": [
@@ -434,7 +592,7 @@ describe("blockESLint", () => {
 				{ ignores: ["generated", "lib", "node_modules", "pnpm-lock.yaml"] },
 				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
 				eslint.configs.recommended,
-				a.configs.recommended,{ extends: [b.configs.recommended], files: ["**/*.b"], rules: {"b/c":"error","b/d":["error",{"e":"f"}]}, },{ extends: [c.configs.recommended], rules: {"c/d":"error","c/e":["error",{"f":"g"}]}, },{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.js", "**/*.ts"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, rules: {"a/b":"error","a/c":["error",{"d":"e"}]}, settings: {"react":{"version":"detect"}}, }
+				a.configs.recommended,{ extends: [b.configs.recommended], files: ["**/*.b"], rules: {"b/c":"error","b/d":["error",{"e":"f"}]}, },{ extends: [c.configs.recommended], rules: {"c/d":"error","c/e":["error",{"f":"g"}]}, },{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, rules: {"a/b":"error","a/c":["error",{"d":"e"}]}, settings: {"react":{"version":"detect"}}, }
 			);",
 			  },
 			  "scripts": [
@@ -570,7 +728,7 @@ describe("blockESLint", () => {
 				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
 				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
 				eslint.configs.recommended,
-				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.js", "**/*.ts"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, rules: {
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, rules: {
 
 			// One line
 			"a": "error",
@@ -708,7 +866,7 @@ describe("blockESLint", () => {
 				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
 				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
 				eslint.configs.recommended,
-				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.js", "**/*.ts"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s","bin/index.js"]},"tsconfigRootDir":import.meta.dirname}}, }
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s","bin/index.js"]},"tsconfigRootDir":import.meta.dirname}}, }
 			);",
 			  },
 			  "scripts": [
@@ -834,7 +992,253 @@ describe("blockESLint", () => {
 				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
 				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
 				eslint.configs.recommended,
-				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.js", "**/*.ts"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s","bin/index.js"]},"tsconfigRootDir":import.meta.dirname}}, }
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s","bin/index.js"]},"tsconfigRootDir":import.meta.dirname}}, }
+			);",
+			  },
+			  "scripts": [
+			    {
+			      "commands": [
+			        "pnpm lint --fix",
+			      ],
+			      "phase": 3,
+			    },
+			  ],
+			}
+		`);
+	});
+
+	test("with options.type set to commonjs", () => {
+		const creation = testBlock(blockESLint, {
+			options: {
+				...optionsBase,
+				type: "commonjs",
+			},
+		});
+
+		expect(creation).toMatchInlineSnapshot(`
+			{
+			  "addons": [
+			    {
+			      "addons": {
+			        "sections": {
+			          "Linting": {
+			            "contents": {
+			              "after": [
+			                "
+			For example, ESLint can be run with \`--fix\` to auto-fix some lint rule complaints:
+
+			\`\`\`shell
+			pnpm run lint --fix
+			\`\`\`
+			",
+			              ],
+			              "before": "
+			This package includes several forms of linting to enforce consistent code quality and styling.
+			Each should be shown in VS Code, and can be run manually on the command-line:
+			",
+			              "items": [
+			                "- \`pnpm lint\` ([ESLint](https://eslint.org) with [typescript-eslint](https://typescript-eslint.io)): Lints JavaScript and TypeScript source files",
+			              ],
+			              "plural": "Read the individual documentation for each linter to understand how it can be configured and used best.",
+			            },
+			          },
+			        },
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "jobs": [
+			          {
+			            "name": "Lint",
+			            "steps": [
+			              {
+			                "run": "pnpm lint",
+			              },
+			            ],
+			          },
+			        ],
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "properties": {
+			          "devDependencies": {
+			            "@eslint/js": "9.22.0",
+			            "@types/node": "22.13.10",
+			            "eslint": "9.22.0",
+			            "typescript-eslint": "8.26.1",
+			          },
+			          "scripts": {
+			            "lint": "eslint . --max-warnings 0",
+			          },
+			        },
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "extensions": [
+			          "dbaeumer.vscode-eslint",
+			        ],
+			        "settings": {
+			          "editor.codeActionsOnSave": {
+			            "source.fixAll.eslint": "explicit",
+			          },
+			          "eslint.probe": [
+			            "javascript",
+			            "javascriptreact",
+			            "json",
+			            "jsonc",
+			            "markdown",
+			            "typescript",
+			            "typescriptreact",
+			            "yaml",
+			          ],
+			          "eslint.rules.customizations": [
+			            {
+			              "rule": "*",
+			              "severity": "warn",
+			            },
+			          ],
+			        },
+			      },
+			      "block": [Function],
+			    },
+			  ],
+			  "files": {
+			    "eslint.config.mjs": "import eslint from "@eslint/js";
+			import tseslint from "typescript-eslint";
+
+			export default tseslint.config(
+				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
+				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
+				eslint.configs.recommended,
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,mjs,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, },{ files: ["*.mjs"], languageOptions: {"sourceType":"module"}, }
+			);",
+			  },
+			  "scripts": [
+			    {
+			      "commands": [
+			        "pnpm lint --fix",
+			      ],
+			      "phase": 3,
+			    },
+			  ],
+			}
+		`);
+	});
+
+	test("with options.type set to module", () => {
+		const creation = testBlock(blockESLint, {
+			options: {
+				...optionsBase,
+				type: "module",
+			},
+		});
+
+		expect(creation).toMatchInlineSnapshot(`
+			{
+			  "addons": [
+			    {
+			      "addons": {
+			        "sections": {
+			          "Linting": {
+			            "contents": {
+			              "after": [
+			                "
+			For example, ESLint can be run with \`--fix\` to auto-fix some lint rule complaints:
+
+			\`\`\`shell
+			pnpm run lint --fix
+			\`\`\`
+			",
+			              ],
+			              "before": "
+			This package includes several forms of linting to enforce consistent code quality and styling.
+			Each should be shown in VS Code, and can be run manually on the command-line:
+			",
+			              "items": [
+			                "- \`pnpm lint\` ([ESLint](https://eslint.org) with [typescript-eslint](https://typescript-eslint.io)): Lints JavaScript and TypeScript source files",
+			              ],
+			              "plural": "Read the individual documentation for each linter to understand how it can be configured and used best.",
+			            },
+			          },
+			        },
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "jobs": [
+			          {
+			            "name": "Lint",
+			            "steps": [
+			              {
+			                "run": "pnpm lint",
+			              },
+			            ],
+			          },
+			        ],
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "properties": {
+			          "devDependencies": {
+			            "@eslint/js": "9.22.0",
+			            "@types/node": "22.13.10",
+			            "eslint": "9.22.0",
+			            "typescript-eslint": "8.26.1",
+			          },
+			          "scripts": {
+			            "lint": "eslint . --max-warnings 0",
+			          },
+			        },
+			      },
+			      "block": [Function],
+			    },
+			    {
+			      "addons": {
+			        "extensions": [
+			          "dbaeumer.vscode-eslint",
+			        ],
+			        "settings": {
+			          "editor.codeActionsOnSave": {
+			            "source.fixAll.eslint": "explicit",
+			          },
+			          "eslint.probe": [
+			            "javascript",
+			            "javascriptreact",
+			            "json",
+			            "jsonc",
+			            "markdown",
+			            "typescript",
+			            "typescriptreact",
+			            "yaml",
+			          ],
+			          "eslint.rules.customizations": [
+			            {
+			              "rule": "*",
+			              "severity": "warn",
+			            },
+			          ],
+			        },
+			      },
+			      "block": [Function],
+			    },
+			  ],
+			  "files": {
+			    "eslint.config.js": "import eslint from "@eslint/js";
+			import tseslint from "typescript-eslint";
+
+			export default tseslint.config(
+				{ ignores: ["lib", "node_modules", "pnpm-lock.yaml"] },
+				{ linterOptions: {"reportUnusedDisableDirectives":"error"} },
+				eslint.configs.recommended,
+				{ extends: [tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked], files: ["**/*.{js,ts}"], languageOptions: {"parserOptions":{"projectService":{"allowDefaultProject":["*.config.*s"]},"tsconfigRootDir":import.meta.dirname}}, }
 			);",
 			  },
 			  "scripts": [
diff --git a/src/blocks/blockPackageJson.test.ts b/src/blocks/blockPackageJson.test.ts
index 793244e..2e79798 100644
--- a/src/blocks/blockPackageJson.test.ts
+++ b/src/blocks/blockPackageJson.test.ts
@@ -131,14 +131,12 @@ describe("blockPackageJson", () => {
 		`);
 	});
 
-	test("with addons adding type", () => {
+	test("with options.type set to commonjs", () => {
 		const creation = testBlock(blockPackageJson, {
-			addons: {
-				properties: {
-					type: "commonjs",
-				},
+			options: {
+				...options,
+				type: "commonjs",
 			},
-			options,
 		});
 
 		expect(creation).toMatchInlineSnapshot(`