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

Issue:
🚀 Feature: Add explicit sizing for README.md logo, if provided
### 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.

### Overview

This repository makes use of the `--logo` option from #851 + #1166:

https://github.com/JoshuaKGoldberg/create-typescript-app/blob/e388ba20f86ac0ac2ffb3245d3d26c96cbc265b1/README.md?plain=1#L18

But, note how there's no explicit image `height` or `width` attribute in there. That means the page won't know how to account for the image's size until it loads in. Kind of a performance issue.

In https://github.com/JoshuaKGoldberg/all-contributors-auto-action/pull/188 I added a logo to the `all-contributors-auto-action` repository that does have explicit `height` and `width` attributes. Let's add in explicit `height` and `width` to this template too!

### Additional Info

The logo image is created here: https://github.com/JoshuaKGoldberg/create-typescript-app/blob/e388ba20f86ac0ac2ffb3245d3d26c96cbc265b1/src/steps/writeReadme/generateTopContent.ts#L64

However, I think this feature shouldn't assume a 128px by 128px image. It should:

1. Read in the logo as an image file from disk
    * If the image file doesn't exist or can't be read as an image, throw an error
2. Use Math.min(image size, 128px) for both height and width
    * If either are > 192px, log a warning that it shouldn't be used as a logo

Pull request:
feat: add logo.height and logo.width
## PR Checklist

- [x] Addresses an existing open issue: fixes #1203
- [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

Uses [`image-size`](https://github.com/image-size/image-size) to read from disk, if possible.

Caps sizes to 128px. Doesn't bother adding a warning logo - I don't feel strongly about it, and have yet to have come across a situation where I would have been helped by that.

💖 

Patch:
diff --git a/README.md b/README.md
index ecbd31e..a740d62 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
 	<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 </p>
 
-<img align="right" alt="Project logo: the TypeScript blue square with rounded corners, but a plus sign instead of 'TS'" src="./docs/create-typescript-app.png">
+<img align="right" alt="Project logo: the TypeScript blue square with rounded corners, but a plus sign instead of 'TS'" height="128" src="./docs/create-typescript-app.png" width="128">
 
 `create-typescript-app` is a one-stop-shop solution to set up a new or existing repository with the latest and greatest TypeScript tooling.
 It includes options not just for building and testing but also GitHub repository templates, contributor recognition, automated release management, and more.
diff --git a/docs/Options.md b/docs/Options.md
index a53824f..3402cad 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -64,6 +64,8 @@ The setup scripts also allow for optional overrides of the following inputs whos
   - This can be specified any number of times, like `--keywords apple --keywords "banana cherry"`
 - `--logo` _(`string`)_: Local image file in the repository to display near the top of the README.md
   - `--logo-alt` _(`string`)_: If `--logo` is provided or detected from an existing README.md, alt text that describes the image (will be prompted for if not provided)
+  - `--logo-height` _(`number`)_: If `--logo` is provided or detected from an existing README.md, an explicit height style (by default, read from the image, capped to `128`)
+  - `--logo-width` _(`number`)_: If `--logo` is provided or detected from an existing README.md, an explicit width style (by default, read from the image, capped to `128`)
 - `--preserve-generated-from` _(`boolean`)_: Whether to keep the GitHub repository _generated from_ notice (by default, `false`)
 
 For example, customizing the ownership and users associated with a new repository:
diff --git a/package.json b/package.json
index eeaeb07..e690069 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
 		"execa": "^9.5.2",
 		"git-remote-origin-url": "^4.0.0",
 		"git-url-parse": "^16.0.0",
+		"image-size": "^1.2.0",
 		"input-from-file": "0.1.0-alpha.4",
 		"input-from-file-json": "0.1.0-alpha.4",
 		"input-from-script": "0.1.0-alpha.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3fafabd..30b632e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -32,6 +32,9 @@ importers:
       git-url-parse:
         specifier: ^16.0.0
         version: 16.0.0
+      image-size:
+        specifier: ^1.2.0
+        version: 1.2.0
       input-from-file:
         specifier: 0.1.0-alpha.4
         version: 0.1.0-alpha.4(create@0.1.0-alpha.8(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2))
@@ -2657,6 +2660,11 @@ packages:
     resolution: {integrity: sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==}
     engines: {node: '>= 4'}
 
+  image-size@1.2.0:
+    resolution: {integrity: sha512-4S8fwbO6w3GeCVN6OPtA9I5IGKkcDMPcKndtUlpJuCwu7JLjtj7JZpwqLuyY2nrmQT3AWsCJLSKPsc2mPBSl3w==}
+    engines: {node: '>=16.x'}
+    hasBin: true
+
   import-fresh@3.3.0:
     resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
     engines: {node: '>=6'}
@@ -3638,6 +3646,9 @@ packages:
   queue-microtask@1.2.3:
     resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
 
+  queue@6.0.2:
+    resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==}
+
   rc@1.2.8:
     resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
     hasBin: true
@@ -6897,6 +6908,10 @@ snapshots:
 
   ignore@6.0.2: {}
 
+  image-size@1.2.0:
+    dependencies:
+      queue: 6.0.2
+
   import-fresh@3.3.0:
     dependencies:
       parent-module: 1.0.1
@@ -8006,6 +8021,10 @@ snapshots:
 
   queue-microtask@1.2.3: {}
 
+  queue@6.0.2:
+    dependencies:
+      inherits: 2.0.4
+
   rc@1.2.8:
     dependencies:
       deep-extend: 0.6.0
diff --git a/src/next/base.ts b/src/next/base.ts
index b212851..07e53bc 100644
--- a/src/next/base.ts
+++ b/src/next/base.ts
@@ -95,7 +95,9 @@ export const base = createBase({
 		logo: z
 			.object({
 				alt: z.string(),
+				height: z.number().optional(),
 				src: z.string(),
+				width: z.number().optional(),
 			})
 			.optional()
 			.describe(
diff --git a/src/next/blocks/blockREADME.ts b/src/next/blocks/blockREADME.ts
index c1418c4..5691e3f 100644
--- a/src/next/blocks/blockREADME.ts
+++ b/src/next/blocks/blockREADME.ts
@@ -2,6 +2,12 @@ import { z } from "zod";
 
 import { base } from "../base.js";
 
+function printAttributes(attributes: Record<string, number | string>) {
+	return Object.entries(attributes)
+		.map(([key, value]) => `${key}="${value}"`)
+		.join(" ");
+}
+
 export const blockREADME = base.createBlock({
 	about: {
 		name: "README.md",
@@ -12,6 +18,10 @@ export const blockREADME = base.createBlock({
 	produce({ addons, options }) {
 		const { notices } = addons;
 
+		const logo = options.logo
+			? `<img ${printAttributes({ align: "right", ...options.logo })}>`
+			: "";
+
 		return {
 			files: {
 				"README.md": `<h1 align="center">${options.title}</h1>
@@ -30,7 +40,7 @@ export const blockREADME = base.createBlock({
 	<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 </p>
 
-${options.logo ? `<img align="right" alt="${options.logo.alt}" src="${options.logo.src}">` : ""}
+${logo}
 
 ## Usage
 
diff --git a/src/shared/options/args.ts b/src/shared/options/args.ts
index a4325fe..55ee8c3 100644
--- a/src/shared/options/args.ts
+++ b/src/shared/options/args.ts
@@ -231,6 +231,22 @@ export const allArgOptions = {
 		docsSection: "optional",
 		type: "string",
 	},
+	"logo-height": {
+		description: `If ${chalk.cyanBright(
+			"--logo",
+		)} is provided or detected from an existing README.md, 
+  an explicit height style`,
+		docsSection: "optional",
+		type: "string",
+	},
+	"logo-width": {
+		description: `If ${chalk.cyanBright(
+			"--logo",
+		)} is provided or detected from an existing README.md, 
+  an explicit width style`,
+		docsSection: "optional",
+		type: "string",
+	},
 	mode: {
 		description: `Whether to:
   • create: a new repository in a child directory
diff --git a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts b/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
index 2ae4587..2e673c2 100644
--- a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
+++ b/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
@@ -1,6 +1,7 @@
 import lazyValue from "lazy-value";
 
 import { readFileSafe } from "../../readFileSafe.js";
+import { readLogoSizing } from "../readLogoSizing.js";
 
 export function readDefaultsFromReadme() {
 	const readme = lazyValue(async () => await readFileSafe("README.md", ""));
@@ -28,6 +29,7 @@ export function readDefaultsFromReadme() {
 			return {
 				alt: /alt=['"](.+)['"]\s*src=/.exec(tag)?.[1] ?? "Project logo",
 				src,
+				...readLogoSizing(src),
 			};
 		},
 		title: async () => {
diff --git a/src/shared/options/logInferredOptions.ts b/src/shared/options/logInferredOptions.ts
index dc0bacd..833d25c 100644
--- a/src/shared/options/logInferredOptions.ts
+++ b/src/shared/options/logInferredOptions.ts
@@ -23,6 +23,14 @@ export function logInferredOptions(augmentedOptions: InferredOptions) {
 	if (augmentedOptions.logo) {
 		logLine(chalk.gray(`- logo: ${augmentedOptions.logo.src}`));
 		logLine(chalk.gray(`- logo-alt: ${augmentedOptions.logo.alt}`));
+
+		if (augmentedOptions.logo.height) {
+			logLine(chalk.gray(`- logo-height: ${augmentedOptions.logo.height}`));
+		}
+
+		if (augmentedOptions.logo.width) {
+			logLine(chalk.gray(`- logo-width: ${augmentedOptions.logo.width}`));
+		}
 	}
 
 	logLine(chalk.gray(`- owner: ${augmentedOptions.owner}`));
diff --git a/src/shared/options/readLogoSizing.ts b/src/shared/options/readLogoSizing.ts
new file mode 100644
index 0000000..6c78577
--- /dev/null
+++ b/src/shared/options/readLogoSizing.ts
@@ -0,0 +1,41 @@
+import { imageSize } from "image-size";
+
+const maximum = 128;
+
+export interface OptionsLogoSizing {
+	height?: number;
+	width?: number;
+}
+
+export function readLogoSizing(
+	src: string | Uint8Array,
+): OptionsLogoSizing | undefined {
+	const size = imageSizeSafe(src);
+	if (!size) {
+		return undefined;
+	}
+
+	if (!size.height) {
+		return size.width ? { width: Math.min(size.width, maximum) } : undefined;
+	}
+
+	if (!size.width) {
+		return { height: Math.min(size.height, maximum) };
+	}
+
+	if (size.height <= maximum && size.width <= maximum) {
+		return size;
+	}
+
+	return size.height > size.width
+		? { height: maximum, width: (size.width / size.height) * maximum }
+		: { height: (size.height / size.width) * maximum, width: maximum };
+}
+
+function imageSizeSafe(src: string | Uint8Array) {
+	try {
+		return imageSize(src);
+	} catch {
+		return undefined;
+	}
+}
diff --git a/src/shared/options/readOptions.ts b/src/shared/options/readOptions.ts
index 5389c1e..20341bf 100644
--- a/src/shared/options/readOptions.ts
+++ b/src/shared/options/readOptions.ts
@@ -16,6 +16,7 @@ import { getBase } from "./getBase.js";
 import { getPrefillOrPromptedOption } from "./getPrefillOrPromptedOption.js";
 import { logInferredOptions } from "./logInferredOptions.js";
 import { optionsSchema } from "./optionsSchema.js";
+import { readLogoSizing } from "./readLogoSizing.js";
 
 export interface OctokitAndOptions {
 	octokit: Octokit | undefined;
@@ -246,6 +247,8 @@ export async function readOptions(
 
 			logo = { alt: logoAltOption.value, src: options.logo };
 		}
+
+		Object.assign(logo, readLogoSizing(logo.src));
 	}
 
 	let email = options.email ?? (await defaults.email());
diff --git a/src/shared/types.ts b/src/shared/types.ts
index 45619f6..d0be361 100644
--- a/src/shared/types.ts
+++ b/src/shared/types.ts
@@ -30,7 +30,9 @@ export interface OptionsGuide {
 
 export interface OptionsLogo {
 	alt: string;
+	height?: number;
 	src: string;
+	width?: number;
 }
 
 export interface PartialPackageData {
diff --git a/src/steps/uninstallPackages.ts b/src/steps/uninstallPackages.ts
index 4075c2c..696c781 100644
--- a/src/steps/uninstallPackages.ts
+++ b/src/steps/uninstallPackages.ts
@@ -16,6 +16,7 @@ export async function uninstallPackages(offline: boolean | undefined) {
 			"execa",
 			"git-remote-origin-url",
 			"git-url-parse",
+			"image-size",
 			"input-from-file",
 			"input-from-file-json",
 			"input-from-script",


Test patch:
diff --git a/src/bin/help.test.ts b/src/bin/help.test.ts
index 0ce57c9..b6fe1c7 100644
--- a/src/bin/help.test.ts
+++ b/src/bin/help.test.ts
@@ -176,6 +176,16 @@ describe("logHelpText", () => {
 			  --logo-alt (string): If --logo is provided or detected from an existing README.md, 
 			  alt text that describes the image will be prompted for if not provided",
 			  ],
+			  [
+			    "
+			  --logo-height (string): If --logo is provided or detected from an existing README.md, 
+			  an explicit height style",
+			  ],
+			  [
+			    "
+			  --logo-width (string): If --logo is provided or detected from an existing README.md, 
+			  an explicit width style",
+			  ],
 			  [
 			    "
 			  --preserve-generated-from: Whether to keep the GitHub repository generated from 
diff --git a/src/next/blocks/blockREADME.test.ts b/src/next/blocks/blockREADME.test.ts
index 2b4e535..825121a 100644
--- a/src/next/blocks/blockREADME.test.ts
+++ b/src/next/blocks/blockREADME.test.ts
@@ -5,7 +5,7 @@ import { blockREADME } from "./blockREADME.js";
 import { optionsBase } from "./options.fakes.js";
 
 describe("blockREADME", () => {
-	test("options.logo", () => {
+	test("options.logo without sizing", () => {
 		const creation = testBlock(blockREADME, {
 			options: {
 				...optionsBase,
@@ -65,6 +65,68 @@ describe("blockREADME", () => {
 		`);
 	});
 
+	test("options.logo with sizing", () => {
+		const creation = testBlock(blockREADME, {
+			options: {
+				...optionsBase,
+				logo: {
+					alt: "My logo",
+					height: 100,
+					src: "img.jpg",
+					width: 128,
+				},
+			},
+		});
+
+		expect(creation).toMatchInlineSnapshot(`
+			{
+			  "files": {
+			    "README.md": "<h1 align="center">Test Title</h1>
+
+			<p align="center">Test description</p>
+
+			<p align="center">
+				<!-- prettier-ignore-start -->
+				<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
+			<!-- ALL-CONTRIBUTORS-BADGE:END -->
+				<!-- prettier-ignore-end -->
+				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
+				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
+				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
+				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
+				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
+			</p>
+
+			<img align="right" alt="My logo" height="100" src="img.jpg" width="128">
+
+			## Usage
+
+			\`\`\`shell
+			npm i test-repository
+			\`\`\`
+			\`\`\`ts
+			import { greet } from "test-repository";
+
+			greet("Hello, world! 💖");
+			\`\`\`
+
+			## Development
+
+			See [\`.github/CONTRIBUTING.md\`](./.github/CONTRIBUTING.md), then [\`.github/DEVELOPMENT.md\`](./.github/DEVELOPMENT.md).
+			Thanks! 💖
+
+			## Contributors
+
+			<!-- spellchecker: disable -->
+			<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
+			<!-- ALL-CONTRIBUTORS-LIST:END -->
+			<!-- spellchecker: enable -->
+			",
+			  },
+			}
+		`);
+	});
+
 	test("without addons", () => {
 		const creation = testBlock(blockREADME, {
 			options: optionsBase,
diff --git a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts b/src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts
index 712300e..f7dd0a3 100644
--- a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts
+++ b/src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts
@@ -10,6 +10,14 @@ vi.mock("../../readFileSafe.js", () => ({
 	},
 }));
 
+const mockReadLogoSizing = vi.fn().mockResolvedValue({});
+
+vi.mock("../readLogoSizing.js", () => ({
+	get readLogoSizing() {
+		return mockReadLogoSizing;
+	},
+}));
+
 describe("readDefaultsFromReadme", () => {
 	describe("logo", () => {
 		it("defaults to undefined when it cannot be found", async () => {
@@ -87,6 +95,24 @@ nothing.
 			});
 		});
 
+		it("includes sizing when readLogoSizing returns sizing", async () => {
+			const sizing = { height: 117, width: 128 };
+
+			mockReadFileSafe.mockResolvedValue(`
+<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>,
+`);
+
+			mockReadLogoSizing.mockReturnValueOnce(sizing);
+
+			const logo = await readDefaultsFromReadme().logo();
+
+			expect(logo).toEqual({
+				alt: "Project logo: a fancy circle",
+				src: "abc/def.jpg",
+				...sizing,
+			});
+		});
+
 		it("parses when found after a badge image", async () => {
 			mockReadFileSafe.mockResolvedValue(`
 		<a href="#contributors" target="_blank"><img alt="👪 All Contributors: 48" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-48-21bb42.svg" /></a>
diff --git a/src/shared/options/readLogoSizing.test.ts b/src/shared/options/readLogoSizing.test.ts
new file mode 100644
index 0000000..17a19de
--- /dev/null
+++ b/src/shared/options/readLogoSizing.test.ts
@@ -0,0 +1,106 @@
+import { describe, expect, it, vi } from "vitest";
+
+import { readLogoSizing } from "./readLogoSizing.js";
+
+const mockImageSize = vi.fn();
+
+vi.mock("image-size", () => ({
+	get imageSize() {
+		return mockImageSize;
+	},
+}));
+
+const src = "img.jpg";
+
+describe("readLogoSizing", () => {
+	it("returns undefined when imageSize throws an error", () => {
+		mockImageSize.mockImplementationOnce(() => {
+			throw new Error("Oh no!");
+		});
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toBeUndefined();
+	});
+
+	it("returns undefined when imageSize returns neither height nor width", () => {
+		mockImageSize.mockReturnValueOnce({});
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toBeUndefined();
+	});
+
+	it("returns the height when imageSize returns only a height smaller than the maximum", () => {
+		const height = 100;
+
+		mockImageSize.mockReturnValueOnce({ height });
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toEqual({ height });
+	});
+
+	it("returns maximum height when imageSize returns only a height greater than the maximum", () => {
+		const height = 129;
+
+		mockImageSize.mockReturnValueOnce({ height });
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toEqual({ height: 128 });
+	});
+
+	it("returns the width when imageSize returns only a width smaller than the maximum", () => {
+		const width = 100;
+
+		mockImageSize.mockReturnValueOnce({ width });
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toEqual({ width });
+	});
+
+	it("returns maximum width when imageSize returns only a width greater than the maximum", () => {
+		const width = 129;
+
+		mockImageSize.mockReturnValueOnce({ width });
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toEqual({ width: 128 });
+	});
+
+	it("returns the height and width when imageSize returns height and width smaller than the maximum", () => {
+		const height = 101;
+		const width = 102;
+
+		mockImageSize.mockReturnValueOnce({ height, width });
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toEqual({ height, width });
+	});
+
+	it("returns the same aspect ratio when imageSize returns a tall image greater than the maximum", () => {
+		const height = 1280;
+		const width = 1000;
+
+		mockImageSize.mockReturnValueOnce({ height, width });
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toEqual({ height: 128, width: 100 });
+	});
+
+	it("returns the same aspect ratio when imageSize returns a wide image greater than the maximum", () => {
+		const height = 1000;
+		const width = 1280;
+
+		mockImageSize.mockReturnValueOnce({ height, width });
+
+		const actual = readLogoSizing(src);
+
+		expect(actual).toEqual({ height: 100, width: 128 });
+	});
+});
diff --git a/src/steps/writing/creation/index.test.ts b/src/steps/writing/creation/index.test.ts
index 92791c7..027bff8 100644
--- a/src/steps/writing/creation/index.test.ts
+++ b/src/steps/writing/creation/index.test.ts
@@ -213,6 +213,7 @@ describe("createStructure", () => {
 						"execa",
 						"git-remote-origin-url",
 						"git-url-parse",
+						"image-size",
 						"input-from-file",
 						"input-from-file-json",
 						"input-from-script",