Repository: sveltejs/cli
Pull request #422 (2025-01-23 20:11:29)

feat: add `tailwindcss` 4.0
- [x] Tests updated to `oklch` 
- [x] Typography is working with out any plugin 🥳

changeset-bot[bot]: ###  🦋  Changeset detected

Latest commit: 84b80b870c34305f34fecc3ee9e4108c2d56c122

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 1 package</summary>

  | Name             | Type  |
| ---------------- | ----- |
| @sveltejs/addons | Patch |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/jycouet/cli/new/feat/tailwindcss-4?filename=.changeset/rotten-carpets-worry.md&value=---%0A%22%40sveltejs%2Faddons%22%3A%20patch%0A---%0A%0Afeat%3A%20ADD%20tailwindcss%204.0%0A)



Patch:
diff --git a/.changeset/empty-geese-draw.md b/.changeset/empty-geese-draw.md
new file mode 100644
index 0000000..893102b
--- /dev/null
+++ b/.changeset/empty-geese-draw.md
@@ -0,0 +1,5 @@
+---
+'sv': patch
+---
+
+feat: update to `tailwindcss` v4.0.0
diff --git a/.changeset/fast-panthers-smile.md b/.changeset/fast-panthers-smile.md
new file mode 100644
index 0000000..a9e1376
--- /dev/null
+++ b/.changeset/fast-panthers-smile.md
@@ -0,0 +1,5 @@
+---
+'sv': patch
+---
+
+feat: support `pnpm` version `10`
diff --git a/.github/workflows/docs-preview-create-request.yml b/.github/workflows/docs-preview-create-request.yml
deleted file mode 100644
index 90bfa2b..0000000
--- a/.github/workflows/docs-preview-create-request.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-# https://github.com/sveltejs/svelte.dev/blob/main/apps/svelte.dev/scripts/sync-docs/README.md
-name: Docs preview create request
-
-on:
-  pull_request_target:
-    branches:
-      - main
-
-jobs:
-  dispatch:
-    runs-on: ubuntu-latest
-    steps:
-      - name: Repository Dispatch
-        uses: peter-evans/repository-dispatch@v3
-        with:
-          token: ${{ secrets.SYNC_REQUEST_TOKEN }}
-          repository: sveltejs/svelte.dev
-          event-type: docs-preview-create
-          client-payload: |-
-            {
-              "package": "cli",
-              "repo": "${{ github.repository }}",
-              "owner": "${{ github.event.pull_request.head.repo.owner.login }}",
-              "branch": "${{ github.event.pull_request.head.ref }}",
-              "pr": ${{ github.event.pull_request.number }}
-            }
diff --git a/.github/workflows/docs-preview-delete-request.yml b/.github/workflows/docs-preview-delete-request.yml
deleted file mode 100644
index 2971a6b..0000000
--- a/.github/workflows/docs-preview-delete-request.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-# https://github.com/sveltejs/svelte.dev/blob/main/apps/svelte.dev/scripts/sync-docs/README.md
-name: Docs preview delete request
-
-on:
-  pull_request_target:
-    branches:
-      - main
-    types: [closed]
-
-jobs:
-  dispatch:
-    runs-on: ubuntu-latest
-    steps:
-      - name: Repository Dispatch
-        uses: peter-evans/repository-dispatch@v3
-        with:
-          token: ${{ secrets.SYNC_REQUEST_TOKEN }}
-          repository: sveltejs/svelte.dev
-          event-type: docs-preview-delete
-          client-payload: |-
-            {
-              "package": "cli",
-              "repo": "${{ github.repository }}",
-              "owner": "${{ github.event.pull_request.head.repo.owner.login }}",
-              "branch": "${{ github.event.pull_request.head.ref }}",
-              "pr": ${{ github.event.pull_request.number }}
-            }
diff --git a/.github/workflows/sync-request.yml b/.github/workflows/sync-request.yml
deleted file mode 100644
index 9843e0d..0000000
--- a/.github/workflows/sync-request.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-# https://github.com/sveltejs/svelte.dev/blob/main/apps/svelte.dev/scripts/sync-docs/README.md
-name: Sync request
-
-on:
-  push:
-    branches:
-      - main
-
-jobs:
-  dispatch:
-    runs-on: ubuntu-latest
-    steps:
-      - name: Repository Dispatch
-        uses: peter-evans/repository-dispatch@v3
-        with:
-          token: ${{ secrets.SYNC_REQUEST_TOKEN }}
-          repository: sveltejs/svelte.dev
-          event-type: sync-request
-          client-payload: |-
-            {
-              "package": "cli"
-            }
diff --git a/documentation/docs/20-commands/30-sv-check.md b/documentation/docs/20-commands/30-sv-check.md
index 4ad025e..52e1a37 100644
--- a/documentation/docs/20-commands/30-sv-check.md
+++ b/documentation/docs/20-commands/30-sv-check.md
@@ -121,7 +121,7 @@ The first row is of type `START` and contains the workspace folder (wrapped in q
 1590680325583 START "/home/user/language-tools/packages/language-server/test/plugins/typescript/testfiles"
 ```
 
-Any number of `ERROR` or `WARNING` records may follow. Their structure is identical and depends on the output argoument.
+Any number of `ERROR` or `WARNING` records may follow. Their structure is identical and depends on the output argument.
 
 If the argument is `machine` it will tell us the filename, the starting line and column numbers, and the error message. The filename is relative to the workspace directory. The filename and the message are both wrapped in quotes. Example:
 
diff --git a/documentation/docs/20-commands/40-sv-migrate.md b/documentation/docs/20-commands/40-sv-migrate.md
index 4283a5e..87e6956 100644
--- a/documentation/docs/20-commands/40-sv-migrate.md
+++ b/documentation/docs/20-commands/40-sv-migrate.md
@@ -8,6 +8,11 @@ Some migrations may annotate your codebase with tasks for completion that you ca
 
 ## Usage
 
+```bash
+npx sv migrate
+```
+
+You can also specify a migration directly via the CLI:
 ```bash
 npx sv migrate [migration]
 ```
diff --git a/eslint.config.js b/eslint.config.js
index c4a0d0c..a5cb3b1 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -31,7 +31,7 @@ export default [
 			'**/.test-output/*',
 			'**/dist/*',
 			'packages/**/tests/**/{output,input}.ts',
-			'rollup.config.js',
+			'rolldown.config.js',
 			'community-addon-template/tests/*'
 		]
 	}
diff --git a/package.json b/package.json
index eab6815..1dab2e7 100644
--- a/package.json
+++ b/package.json
@@ -5,13 +5,13 @@
 	"type": "module",
 	"description": "monorepo for sv and friends",
 	"engines": {
-		"pnpm": "^9.0.0"
+		"pnpm": "^10.0.0"
 	},
 	"scripts": {
-		"build": "rollup -c",
+		"build": "rolldown --config",
 		"changeset:publish": "changeset publish",
 		"check": "pnpm --parallel check",
-		"dev": "rollup --config --watch",
+		"dev": "rolldown --watch --config",
 		"format": "pnpm --parallel format",
 		"lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache",
 		"test": "vitest run --silent",
@@ -21,10 +21,6 @@
 	"devDependencies": {
 		"@changesets/cli": "^2.27.10",
 		"@playwright/test": "^1.49.1",
-		"@rollup/plugin-commonjs": "^28.0.2",
-		"@rollup/plugin-dynamic-import-vars": "^2.1.5",
-		"@rollup/plugin-json": "^6.1.0",
-		"@rollup/plugin-node-resolve": "^15.3.0",
 		"@sveltejs/create": "workspace:*",
 		"@sveltejs/eslint-config": "^8.1.0",
 		"@svitejs/changesets-changelog-github-compact": "^1.2.0",
@@ -35,9 +31,7 @@
 		"prettier": "^3.4.2",
 		"prettier-plugin-packagejson": "^2.5.6",
 		"prettier-plugin-svelte": "^3.3.2",
-		"rollup": "^4.28.1",
-		"rollup-plugin-esbuild": "^6.1.1",
-		"rollup-plugin-preserve-shebangs": "^0.2.0",
+		"rolldown": "1.0.0-beta.1",
 		"sv": "workspace:*",
 		"svelte": "^5.12.0",
 		"typescript": "^5.6.2",
@@ -45,5 +39,5 @@
 		"unplugin-isolated-decl": "^0.8.3",
 		"vitest": "^3.0.3"
 	},
-	"packageManager": "pnpm@9.7.0"
+	"packageManager": "pnpm@10.1.0"
 }
diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts
index 698cdc1..0cf8fa6 100644
--- a/packages/addons/drizzle/index.ts
+++ b/packages/addons/drizzle/index.ts
@@ -89,6 +89,7 @@ export default defineAddon({
 		if (options.sqlite === 'better-sqlite3') {
 			sv.dependency('better-sqlite3', '^11.8.0');
 			sv.devDependency('@types/better-sqlite3', '^7.6.12');
+			sv.pnpmBuildDependendency('better-sqlite3');
 		}
 
 		if (options.sqlite === 'libsql' || options.sqlite === 'turso')
diff --git a/packages/addons/tailwindcss/index.ts b/packages/addons/tailwindcss/index.ts
index 80c581b..914e200 100644
--- a/packages/addons/tailwindcss/index.ts
+++ b/packages/addons/tailwindcss/index.ts
@@ -1,130 +1,50 @@
-import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core';
+import { defineAddon } from '@sveltejs/cli-core';
 import { addImports } from '@sveltejs/cli-core/css';
-import { array, common, exports, imports, object } from '@sveltejs/cli-core/js';
-import { parseCss, parseScript, parseJson, parseSvelte } from '@sveltejs/cli-core/parsers';
+import { array, functions, imports, object, exports } from '@sveltejs/cli-core/js';
+import { parseCss, parseJson, parseScript, parseSvelte } from '@sveltejs/cli-core/parsers';
 import { addSlot } from '@sveltejs/cli-core/html';
 
-type Plugin = {
-	id: string;
-	package: string;
-	version: string;
-	identifier: string;
-};
-
-const plugins: Plugin[] = [
-	{
-		id: 'typography',
-		package: '@tailwindcss/typography',
-		version: '^0.5.16',
-		identifier: 'typography'
-	},
-	{
-		id: 'forms',
-		package: '@tailwindcss/forms',
-		version: '^0.5.10',
-		identifier: 'forms'
-	},
-	{
-		id: 'container-queries',
-		package: '@tailwindcss/container-queries',
-		version: '^0.1.1',
-		identifier: 'containerQueries'
-	}
-];
-
-const options = defineAddonOptions({
-	plugins: {
-		type: 'multiselect',
-		question: 'Which plugins would you like to add?',
-		options: plugins.map((p) => ({ value: p.id, label: p.id, hint: p.package })),
-		default: []
-	}
-});
-
 export default defineAddon({
 	id: 'tailwindcss',
 	alias: 'tailwind',
 	shortDescription: 'css framework',
 	homepage: 'https://tailwindcss.com',
-	options,
-	run: ({ sv, options, typescript, kit, dependencyVersion }) => {
+	options: {},
+	run: ({ sv, typescript, kit, dependencyVersion }) => {
 		const ext = typescript ? 'ts' : 'js';
 		const prettierInstalled = Boolean(dependencyVersion('prettier'));
 
-		sv.devDependency('tailwindcss', '^3.4.17');
-		sv.devDependency('autoprefixer', '^10.4.20');
-
-		if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.10');
+		sv.devDependency('tailwindcss', '^4.0.0');
+		sv.devDependency('@tailwindcss/vite', '^4.0.0');
 
-		for (const plugin of plugins) {
-			if (!options.plugins.includes(plugin.id)) continue;
+		if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.11');
 
-			sv.devDependency(plugin.package, plugin.version);
-		}
-
-		sv.file(`tailwind.config.${ext}`, (content) => {
+		// add the vite plugin
+		sv.file(`vite.config.${ext}`, (content) => {
 			const { ast, generateCode } = parseScript(content);
-			let root;
-			const rootExport = object.createEmpty();
-			if (typescript) {
-				imports.addNamed(ast, 'tailwindcss', { Config: 'Config' }, true);
-				root = common.satisfiesExpression(rootExport, 'Config');
-			}
-
-			const { astNode: exportDeclaration, value: node } = exports.defaultExport(
-				ast,
-				root ?? rootExport
-			);
-
-			const config = node.type === 'TSSatisfiesExpression' ? node.expression : node;
-			if (config.type !== 'ObjectExpression') {
-				throw new Error(`Unexpected tailwind config shape: ${config.type}`);
-			}
-
-			if (!typescript) {
-				common.addJsDocTypeComment(exportDeclaration, "import('tailwindcss').Config");
-			}
-
-			const contentArray = object.property(config, 'content', array.createEmpty());
-			array.push(contentArray, './src/**/*.{html,js,svelte,ts}');
-
-			const themeObject = object.property(config, 'theme', object.createEmpty());
-			object.property(themeObject, 'extend', object.createEmpty());
 
-			const pluginsArray = object.property(config, 'plugins', array.createEmpty());
+			const vitePluginName = 'tailwindcss';
+			imports.addDefault(ast, '@tailwindcss/vite', vitePluginName);
 
-			for (const plugin of plugins) {
-				if (!options.plugins.includes(plugin.id)) continue;
-				imports.addDefault(ast, plugin.package, plugin.identifier);
-				array.push(pluginsArray, { type: 'Identifier', name: plugin.identifier });
-			}
+			const { value: rootObject } = exports.defaultExport(ast, functions.call('defineConfig', []));
+			const param1 = functions.argumentByIndex(rootObject, 0, object.createEmpty());
 
-			return generateCode();
-		});
-
-		sv.file('postcss.config.js', (content) => {
-			const { ast, generateCode } = parseScript(content);
-			const { value: rootObject } = exports.defaultExport(ast, object.createEmpty());
-			const pluginsObject = object.property(rootObject, 'plugins', object.createEmpty());
+			const pluginsArray = object.property(param1, 'plugins', array.createEmpty());
+			const pluginFunctionCall = functions.call(vitePluginName, []);
+			array.push(pluginsArray, pluginFunctionCall);
 
-			object.property(pluginsObject, 'tailwindcss', object.createEmpty());
-			object.property(pluginsObject, 'autoprefixer', object.createEmpty());
 			return generateCode();
 		});
 
 		sv.file('src/app.css', (content) => {
-			const layerImports = ['base', 'components', 'utilities'].map(
-				(layer) => `tailwindcss/${layer}`
-			);
-			if (layerImports.every((i) => content.includes(i))) {
+			if (content.includes('tailwindcss')) {
 				return content;
 			}
 
 			const { ast, generateCode } = parseCss(content);
 			const originalFirst = ast.first;
 
-			const specifiers = layerImports.map((i) => `'${i}'`);
-			const nodes = addImports(ast, specifiers);
+			const nodes = addImports(ast, ["'tailwindcss'"]);
 
 			if (
 				originalFirst !== ast.first &&
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index c7042c7..5a55c78 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -1,5 +1,20 @@
 # sv
 
+## 0.6.18
+### Patch Changes
+
+
+- fix: `checkjs` library template ([#428](https://github.com/sveltejs/cli/pull/428))
+
+## 0.6.17
+### Patch Changes
+
+
+- fix: properly pass through arguments to `sv check` ([#420](https://github.com/sveltejs/cli/pull/420))
+
+
+- chore: use `rolldown` instead of `rollup` ([#371](https://github.com/sveltejs/cli/pull/371))
+
 ## 0.6.16
 ### Patch Changes
 
diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts
index 32014c3..054b47b 100644
--- a/packages/cli/commands/add/index.ts
+++ b/packages/cli/commands/add/index.ts
@@ -18,7 +18,11 @@ import * as common from '../../utils/common.ts';
 import { createWorkspace } from './workspace.ts';
 import { formatFiles, getHighlighter } from './utils.ts';
 import { Directive, downloadPackage, getPackageJSON } from './fetch-packages.ts';
-import { installDependencies, packageManagerPrompt } from '../../utils/package-manager.ts';
+import {
+	addPnpmBuildDependendencies,
+	installDependencies,
+	packageManagerPrompt
+} from '../../utils/package-manager.ts';
 import { getGlobalPreconditions } from './preconditions.ts';
 import { type AddonMap, applyAddons, setupAddons } from '../../lib/install.ts';
 
@@ -425,13 +429,6 @@ export async function runAddCommand(
 	// indicating that installing deps was skipped and no PM was selected
 	if (selectedAddons.length === 0) return { packageManager: null };
 
-	// prompt for package manager
-	let packageManager: PackageManager | undefined;
-	if (options.install) {
-		packageManager = await packageManagerPrompt(options.cwd);
-		if (packageManager) workspace.packageManager = packageManager;
-	}
-
 	// apply addons
 	const officialDetails = Object.keys(official).map((id) => getAddonDetails(id));
 	const commDetails = Object.keys(community).map(
@@ -440,7 +437,7 @@ export async function runAddCommand(
 	const details = officialDetails.concat(commDetails);
 
 	const addonMap: AddonMap = Object.assign({}, ...details.map((a) => ({ [a.id]: a })));
-	const filesToFormat = await applyAddons({
+	const { filesToFormat, pnpmBuildDependencies: addonPnpmBuildDependencies } = await applyAddons({
 		workspace,
 		addonSetupResults,
 		addons: addonMap,
@@ -449,9 +446,21 @@ export async function runAddCommand(
 
 	p.log.success('Successfully setup add-ons');
 
-	// install dependencies
-	if (packageManager && options.install) {
-		await installDependencies(packageManager, options.cwd);
+	// prompt for package manager and install dependencies
+	let packageManager: PackageManager | undefined;
+	if (options.install) {
+		packageManager = await packageManagerPrompt(options.cwd);
+
+		if (packageManager) {
+			workspace.packageManager = packageManager;
+
+			addPnpmBuildDependendencies(workspace.cwd, packageManager, [
+				'esbuild',
+				...addonPnpmBuildDependencies
+			]);
+
+			await installDependencies(packageManager, options.cwd);
+		}
 	}
 
 	// format modified/created files with prettier (if available)
diff --git a/packages/cli/commands/check.ts b/packages/cli/commands/check.ts
index d436c61..aa3117c 100644
--- a/packages/cli/commands/check.ts
+++ b/packages/cli/commands/check.ts
@@ -11,6 +11,7 @@ export const check = new Command('check')
 	.description('a CLI for checking your Svelte code')
 	// flags that we'll want to pass to `svelte-check`
 	.allowUnknownOption(true)
+	.allowExcessArguments(true)
 	.option('-C, --cwd <path>', 'path to working directory', process.cwd())
 	.configureHelp({
 		formatHelp() {
diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts
index d6a8c55..77a5d8c 100644
--- a/packages/cli/commands/create.ts
+++ b/packages/cli/commands/create.ts
@@ -15,6 +15,7 @@ import * as common from '../utils/common.ts';
 import { runAddCommand } from './add/index.ts';
 import { detectSync, resolveCommand, type AgentName } from 'package-manager-detector';
 import {
+	addPnpmBuildDependendencies,
 	getUserAgent,
 	installDependencies,
 	packageManagerPrompt
@@ -164,6 +165,7 @@ async function createProject(cwd: ProjectPath, options: Options) {
 	let addOnNextSteps: string | undefined;
 	const installDeps = async () => {
 		packageManager = await packageManagerPrompt(projectPath);
+		addPnpmBuildDependendencies(projectPath, packageManager, ['esbuild']);
 		if (packageManager) await installDependencies(packageManager, projectPath);
 	};
 
diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts
index 72d5173..6f98ce4 100644
--- a/packages/cli/lib/install.ts
+++ b/packages/cli/lib/install.ts
@@ -33,7 +33,7 @@ export async function installAddon<Addons extends AddonMap>({
 	cwd,
 	options,
 	packageManager = 'npm'
-}: InstallOptions<Addons>): Promise<string[]> {
+}: InstallOptions<Addons>): Promise<ReturnType<typeof applyAddons>> {
 	const workspace = createWorkspace({ cwd, packageManager });
 	const addonSetupResults = setupAddons(Object.values(addons), workspace);
 
@@ -51,8 +51,12 @@ export async function applyAddons({
 	workspace,
 	addonSetupResults,
 	options
-}: ApplyAddonOptions): Promise<string[]> {
+}: ApplyAddonOptions): Promise<{
+	filesToFormat: string[];
+	pnpmBuildDependencies: string[];
+}> {
 	const filesToFormat = new Set<string>();
+	const allPnpmBuildDependencies: string[] = [];
 
 	const mapped = Object.entries(addons).map(([, addon]) => addon);
 	const ordered = orderAddons(mapped, addonSetupResults);
@@ -60,11 +64,20 @@ export async function applyAddons({
 	for (const addon of ordered) {
 		workspace = createWorkspace({ ...workspace, options: options[addon.id] });
 
-		const files = await runAddon({ workspace, addon, multiple: ordered.length > 1 });
+		const { files, pnpmBuildDependencies } = await runAddon({
+			workspace,
+			addon,
+			multiple: ordered.length > 1
+		});
+
 		files.forEach((f) => filesToFormat.add(f));
+		pnpmBuildDependencies.forEach((s) => allPnpmBuildDependencies.push(s));
 	}
 
-	return Array.from(filesToFormat);
+	return {
+		filesToFormat: Array.from(filesToFormat),
+		pnpmBuildDependencies: allPnpmBuildDependencies
+	};
 }
 
 export function setupAddons(
@@ -91,7 +104,7 @@ type RunAddon = {
 	addon: Addon<Record<string, Question>>;
 	multiple: boolean;
 };
-async function runAddon({ addon, multiple, workspace }: RunAddon): Promise<string[]> {
+async function runAddon({ addon, multiple, workspace }: RunAddon) {
 	const files = new Set<string>();
 
 	// apply default addon options
@@ -103,6 +116,7 @@ async function runAddon({ addon, multiple, workspace }: RunAddon): Promise<strin
 	}
 
 	const dependencies: Array<{ pkg: string; version: string; dev: boolean }> = [];
+	const pnpmBuildDependencies: string[] = [];
 	const sv: SvApi = {
 		file: (path, content) => {
 			try {
@@ -150,6 +164,9 @@ async function runAddon({ addon, multiple, workspace }: RunAddon): Promise<strin
 		},
 		devDependency: (pkg, version) => {
 			dependencies.push({ pkg, version, dev: true });
+		},
+		pnpmBuildDependendency: (pkg) => {
+			pnpmBuildDependencies.push(pkg);
 		}
 	};
 	await addon.run({ ...workspace, sv });
@@ -157,7 +174,10 @@ async function runAddon({ addon, multiple, workspace }: RunAddon): Promise<strin
 	const pkgPath = installPackages(dependencies, workspace);
 	files.add(pkgPath);
 
-	return Array.from(files);
+	return {
+		files: Array.from(files),
+		pnpmBuildDependencies
+	};
 }
 
 // sorts them to their execution order
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 2ca5603..aae4a6c 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "sv",
-	"version": "0.6.16",
+	"version": "0.6.18",
 	"type": "module",
 	"description": "A CLI for creating and updating SvelteKit projects",
 	"license": "MIT",
diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts
index 0f979fc..64babcb 100644
--- a/packages/cli/utils/package-manager.ts
+++ b/packages/cli/utils/package-manager.ts
@@ -1,4 +1,7 @@
+import fs from 'node:fs';
+import path from 'node:path';
 import process from 'node:process';
+import * as find from 'empathic/find';
 import { exec } from 'tinyexec';
 import * as p from '@sveltejs/clack-prompts';
 import {
@@ -8,6 +11,7 @@ import {
 	detectSync,
 	type AgentName
 } from 'package-manager-detector';
+import { parseJson } from '@sveltejs/cli-core/parsers';
 
 const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@'));
 const agentOptions: PackageManagerOptions = agents.map((pm) => ({ value: pm, label: pm }));
@@ -67,3 +71,33 @@ export function getUserAgent(): AgentName | undefined {
 	const name = pmSpec.substring(0, separatorPos) as AgentName;
 	return AGENTS.includes(name) ? name : undefined;
 }
+
+export function addPnpmBuildDependendencies(
+	cwd: string,
+	packageManager: AgentName | null | undefined,
+	allowedPackages: string[]
+) {
+	// other package managers are currently not affected by this change
+	if (!packageManager || packageManager !== 'pnpm') return;
+
+	// find the workspace root
+	const pnpmWorkspacePath = find.up('pnpm-workspace.yaml', { cwd });
+	if (!pnpmWorkspacePath) return;
+
+	// load the package.json
+	const pkgPath = path.join(path.dirname(pnpmWorkspacePath), 'package.json');
+	const content = fs.readFileSync(pkgPath, 'utf-8');
+	const { data, generateCode } = parseJson(content);
+
+	// add the packages where we install scripts should be executed
+	data.pnpm ??= {};
+	data.pnpm.onlyBuiltDependencies ??= [];
+	for (const allowedPackage of allowedPackages) {
+		if (data.pnpm.onlyBuiltDependencies.includes(allowedPackage)) continue;
+		data.pnpm.onlyBuiltDependencies.push(allowedPackage);
+	}
+
+	// save the updated package.json
+	const newContent = generateCode();
+	fs.writeFileSync(pkgPath, newContent);
+}
diff --git a/packages/core/addon/config.ts b/packages/core/addon/config.ts
index 9890046..be36f77 100644
--- a/packages/core/addon/config.ts
+++ b/packages/core/addon/config.ts
@@ -20,10 +20,11 @@ export type Scripts<Args extends OptionDefinition> = {
 };
 
 export type SvApi = {
-	file: (path: string, edit: (content: string) => string) => void;
+	pnpmBuildDependendency: (pkg: string) => void;
 	dependency: (pkg: string, version: string) => void;
 	devDependency: (pkg: string, version: string) => void;
 	execute: (args: string[], stdio: 'inherit' | 'pipe') => Promise<void>;
+	file: (path: string, edit: (content: string) => string) => void;
 };
 
 export type Addon<Args extends OptionDefinition> = {
diff --git a/packages/migrate/CHANGELOG.md b/packages/migrate/CHANGELOG.md
index 4528dfc..5b97cca 100644
--- a/packages/migrate/CHANGELOG.md
+++ b/packages/migrate/CHANGELOG.md
@@ -1,5 +1,17 @@
 # svelte-migrate
 
+## 1.9.0
+### Minor Changes
+
+
+- feat: add ability to select migration to run ([#376](https://github.com/sveltejs/cli/pull/376))
+
+
+### Patch Changes
+
+
+- chore: align dependencies with `sv` ([#376](https://github.com/sveltejs/cli/pull/376))
+
 ## 1.8.0
 ### Minor Changes
 
diff --git a/packages/migrate/README.md b/packages/migrate/README.md
index 07ae73a..ed7413b 100644
--- a/packages/migrate/README.md
+++ b/packages/migrate/README.md
@@ -4,13 +4,13 @@ A CLI for migrating Svelte(Kit) codebases.
 
 Run it directly using:
 
-```
-npx svelte-migrate [migration]
+```bash
+npx sv migrate
 ```
 
-Or via the unified Svlete CLI with:
+You can also specify a migration directly via the CLI:
 
-```
+```bash
 npx sv migrate [migration]
 ```
 
diff --git a/packages/migrate/bin.js b/packages/migrate/bin.js
index df8d7de..18f1ad8 100755
--- a/packages/migrate/bin.js
+++ b/packages/migrate/bin.js
@@ -2,7 +2,8 @@
 import fs from 'node:fs';
 import process from 'node:process';
 import { fileURLToPath } from 'node:url';
-import colors from 'kleur';
+import pc from 'picocolors';
+import * as p from '@clack/prompts';
 
 const migration = process.argv[2];
 const dir = fileURLToPath(new URL('.', import.meta.url));
@@ -11,17 +12,29 @@ const migrations = fs
 	.readdirSync(`${dir}/migrations`)
 	.filter((migration) => fs.existsSync(`${dir}/migrations/${migration}/index.js`));
 
+const pkg = JSON.parse(fs.readFileSync(`${dir}/package.json`, 'utf8'));
+
+p.intro(`Welcome to the svelte-migrate CLI! ${pc.gray(`(v${pkg.version})`)}`);
+
 if (migrations.includes(migration)) {
-	const { migrate } = await import(`./migrations/${migration}/index.js`);
-	migrate();
+	await run_migration(migration);
 } else {
-	console.error(
-		colors
-			.bold()
-			.red(
-				`You must specify one of the following migrations: ${migrations.join(', ')}\n` +
-					'If you expected this to work, try re-running the command with the latest svelte-migrate version:\n' +
-					`  npx svelte-migrate@latest ${migration}`
-			)
-	);
+	if (migration) p.log.warning(pc.yellow(`Invalid migration "${migration}" provided.`));
+
+	const selectedMigration = await p.select({
+		message: 'Which migration would you like to run?',
+		options: migrations.map((x) => ({ value: x, label: x }))
+	});
+
+	if (!p.isCancel(selectedMigration)) await run_migration(selectedMigration);
+}
+
+p.outro("You're all set!");
+
+/**
+ * @param {string} migration
+ */
+async function run_migration(migration) {
+	const { migrate } = await import(`./migrations/${migration}/index.js`);
+	await migrate();
 }
diff --git a/packages/migrate/migrations/app-state/index.js b/packages/migrate/migrations/app-state/index.js
index 8ba9a32..b3775e2 100644
--- a/packages/migrate/migrations/app-state/index.js
+++ b/packages/migrate/migrations/app-state/index.js
@@ -1,10 +1,10 @@
-import colors from 'kleur';
+import pc from 'picocolors';
 import fs from 'node:fs';
 import process from 'node:process';
-import prompts from 'prompts';
+import * as p from '@clack/prompts';
 import semver from 'semver';
 import glob from 'tiny-glob/sync.js';
-import { bail, check_git, update_svelte_file } from '../../utils.js';
+import { bail, check_git, migration_succeeded, update_svelte_file } from '../../utils.js';
 import { transform_svelte_code, update_pkg_json } from './migrate.js';
 
 export async function migrate() {
@@ -16,51 +16,46 @@ export async function migrate() {
 
 	const svelte_dep = pkg.devDependencies?.svelte ?? pkg.dependencies?.svelte;
 	if (svelte_dep && semver.validRange(svelte_dep) && semver.gtr('5.0.0', svelte_dep)) {
-		console.log(
-			colors
-				.bold()
-				.red('\nYou need to upgrade to Svelte version 5 first (`npx sv migrate svelte-5`).\n')
+		p.log.error(
+			pc.bold(pc.red('You need to upgrade to Svelte version 5 first (`npx sv migrate svelte-5`).'))
 		);
 		process.exit(1);
 	}
 
 	const kit_dep = pkg.devDependencies?.['@sveltejs/kit'] ?? pkg.dependencies?.['@sveltejs/kit'];
 	if (kit_dep && semver.validRange(kit_dep) && semver.gtr('2.0.0', kit_dep)) {
-		console.log(
-			colors
-				.bold()
-				.red('\nYou need to upgrade to SvelteKit version 2 first (`npx sv migrate sveltekit-2`).\n')
+		p.log.error(
+			pc.bold(
+				pc.red('You need to upgrade to SvelteKit version 2 first (`npx sv migrate sveltekit-2`).')
+			)
 		);
 		process.exit(1);
 	}
 
-	console.log(
-		colors
-			.bold()
-			.yellow(
-				'\nThis will update files in the current directory\n' +
-					"If you're inside a monorepo, don't run this in the root directory, rather run it in all projects independently.\n"
+	p.log.warning(
+		pc.bold(pc.yellow('This will update files in the current directory.')) +
+			'\n' +
+			pc.bold(
+				pc.yellow(
+					"If you're inside a monorepo, don't run this in the root directory, rather run it in all projects independently."
+				)
 			)
 	);
 
 	const use_git = check_git();
 
-	const response = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const response = await p.confirm({
 		message: 'Continue?',
-		initial: false
+		initialValue: false
 	});
 
-	if (!response.value) {
+	if (p.isCancel(response) || !response) {
 		process.exit(1);
 	}
 
-	const folders = await prompts({
-		type: 'multiselect',
-		name: 'value',
+	const folders = await p.multiselect({
 		message: 'Which folders should be migrated?',
-		choices: fs
+		options: fs
 			.readdirSync('.')
 			.filter(
 				(dir) => fs.statSync(dir).isDirectory() && dir !== 'node_modules' && !dir.startsWith('.')
@@ -68,14 +63,14 @@ export async function migrate() {
 			.map((dir) => ({ title: dir, value: dir, selected: true }))
 	});
 
-	if (!folders.value?.length) {
+	if (p.isCancel(folders) || !folders?.length) {
 		process.exit(1);
 	}
 
 	update_pkg_json();
 
 	// For some reason {folders.value.join(',')} as part of the glob doesn't work and returns less files
-	const files = folders.value.flatMap(
+	const files = folders.flatMap(
 		/** @param {string} folder */ (folder) =>
 			glob(`${folder}/**`, { filesOnly: true, dot: true })
 				.map((file) => file.replace(/\\/g, '/'))
@@ -96,24 +91,15 @@ export async function migrate() {
 		);
 	}
 
-	console.log(colors.bold().green('✔ Your project has been migrated'));
-
-	console.log('\nRecommended next steps:\n');
-
-	const cyan = colors.bold().cyan;
-
-	const tasks = [
-		"install the updated dependencies ('npm i' / 'pnpm i' / etc) " + use_git &&
-			cyan('git commit -m "migration to $app/state"')
-	].filter(Boolean);
-
-	tasks.forEach((task, i) => {
-		console.log(`  ${i + 1}: ${task}`);
-	});
-
-	console.log('');
+	/** @type {(s: string) => string} */
+	const cyan = (s) => pc.bold(pc.cyan(s));
 
+	// TODO: use package-manager-detector here
+	const tasks = ["install the updated dependencies ('npm i' / 'pnpm i' / etc)"];
 	if (use_git) {
-		console.log(`Run ${cyan('git diff')} to review changes.\n`);
+		tasks.push(cyan('git commit -m "migration to $app/state"'));
+		tasks.push(`Run ${cyan('git diff')} to review changes.`);
 	}
+
+	migration_succeeded(tasks);
 }
diff --git a/packages/migrate/migrations/package/index.js b/packages/migrate/migrations/package/index.js
index 0e36547..05565ee 100644
--- a/packages/migrate/migrations/package/index.js
+++ b/packages/migrate/migrations/package/index.js
@@ -1,10 +1,10 @@
 import fs from 'node:fs';
-import colors from 'kleur';
+import pc from 'picocolors';
 import path from 'node:path';
 import process from 'node:process';
-import prompts from 'prompts';
+import * as p from '@clack/prompts';
 import { pathToFileURL } from 'node:url';
-import { bail, check_git } from '../../utils.js';
+import { bail, check_git, migration_succeeded } from '../../utils.js';
 import { migrate_config } from './migrate_config.js';
 import { migrate_pkg } from './migrate_pkg.js';
 
@@ -16,24 +16,20 @@ export async function migrate() {
 		bail('Please re-run this script in a directory with a package.json');
 	}
 
-	console.log(
-		colors
-			.bold()
-			.yellow(
-				'\nThis will update your svelte.config.js and package.json in the current directory\n'
-			)
+	p.log.warning(
+		pc.bold(
+			pc.yellow('This will update your svelte.config.js and package.json in the current directory')
+		)
 	);
 
 	const use_git = check_git();
 
-	const response = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const response = await p.confirm({
 		message: 'Continue?',
-		initial: false
+		initialValue: false
 	});
 
-	if (!response.value) {
+	if (p.isCancel(response) || !response) {
 		process.exit(1);
 	}
 
@@ -57,25 +53,16 @@ export async function migrate() {
 		migrate_config();
 	}
 
-	console.log(colors.bold().green('✔ Your project has been migrated'));
+	/** @type {(s: string) => string} */
+	const cyan = (s) => pc.bold(pc.cyan(s));
 
-	console.log('\nRecommended next steps:\n');
+	/** @type {string[]} */
+	const tasks = [];
 
-	const cyan = colors.bold().cyan;
+	if (use_git) tasks.push(cyan('git commit -m "migration to @sveltejs/package v2"'));
 
-	const tasks = [
-		use_git && cyan('git commit -m "migration to @sveltejs/package v2"'),
-		'Review the migration guide at https://github.com/sveltejs/kit/pull/8922',
-		'Read the updated docs at https://svelte.dev/docs/kit/packaging'
-	].filter(Boolean);
+	tasks.push('Review the migration guide at https://github.com/sveltejs/kit/pull/8922');
+	tasks.push('Read the updated docs at https://svelte.dev/docs/kit/packaging');
 
-	tasks.forEach((task, i) => {
-		console.log(`  ${i + 1}: ${task}`);
-	});
-
-	console.log('');
-
-	if (use_git) {
-		console.log(`Run ${cyan('git diff')} to review changes.\n`);
-	}
+	migration_succeeded;
 }
diff --git a/packages/migrate/migrations/package/migrate_config.js b/packages/migrate/migrations/package/migrate_config.js
index b401626..5d42e22 100644
--- a/packages/migrate/migrations/package/migrate_config.js
+++ b/packages/migrate/migrations/package/migrate_config.js
@@ -1,5 +1,6 @@
+import * as p from '@clack/prompts';
 import fs from 'node:fs';
-import colors from 'kleur';
+import pc from 'picocolors';
 import MagicString from 'magic-string';
 import ts from 'typescript';
 
@@ -8,10 +9,12 @@ export function migrate_config() {
 		const content = fs.readFileSync('svelte.config.js', 'utf8');
 		fs.writeFileSync('svelte.config.js', remove_package_from_config(content));
 	} catch {
-		console.log(
-			colors
-				.bold()
-				.yellow('Could not remove package config from svelte.config.js, please remove it manually')
+		p.log.warning(
+			pc.bold(
+				pc.yellow(
+					'Could not remove package config from svelte.config.js, please remove it manually'
+				)
+			)
 		);
 	}
 }
diff --git a/packages/migrate/migrations/package/migrate_pkg.js b/packages/migrate/migrations/package/migrate_pkg.js
index 3e5f5b6..f79a229 100644
--- a/packages/migrate/migrations/package/migrate_pkg.js
+++ b/packages/migrate/migrations/package/migrate_pkg.js
@@ -1,6 +1,7 @@
+import * as p from '@clack/prompts';
 import fs from 'node:fs';
 import path from 'node:path';
-import colors from 'kleur';
+import pc from 'picocolors';
 import { guess_indent, posixify, walk } from '../../utils.js';
 
 /**
@@ -58,8 +59,8 @@ export function update_pkg_json(config, pkg, files) {
 
 	// See: https://pnpm.io/package_json#publishconfigdirectory
 	if (pkg.publishConfig?.directory || pkg.linkDirectory?.directory) {
-		console.log(
-			colors.yellow(
+		p.log.warning(
+			pc.yellow(
 				'Detected "publishConfig.directory" or "linkDirectory.directory" fields in your package.json. ' +
 					'This migration removes them, which may or may not be what you want. Please review closely.'
 			)
@@ -101,8 +102,8 @@ export function update_pkg_json(config, pkg, files) {
 			const key = `./${file.dest}`.replace(/\/index\.js$|(\/[^/]+)\.js$/, '$1');
 
 			if (clashes[key]) {
-				console.log(
-					colors.yellow(
+				p.log.warning(
+					pc.yellow(
 						`Duplicate "${key}" export. Closely review your "exports" field in package.json after the migration.`
 					)
 				);
@@ -169,15 +170,15 @@ export function update_pkg_json(config, pkg, files) {
 			if (svelte_export) {
 				pkg.svelte = svelte_export;
 			} else {
-				console.log(
-					colors.yellow(
+				p.log.warning(
+					pc.yellow(
 						'Cannot generate a "svelte" entry point because the "." entry in "exports" is not a string. Please specify a "svelte" entry point yourself\n'
 					)
 				);
 			}
 		} else {
-			console.log(
-				colors.yellow(
+			p.log.warning(
+				pc.yellow(
 					'Cannot generate a "svelte" entry point because the "." entry in "exports" is missing. Please specify a "svelte" entry point yourself\n'
 				)
 			);
diff --git a/packages/migrate/migrations/routes/index.js b/packages/migrate/migrations/routes/index.js
index 9f04332..fa95d44 100644
--- a/packages/migrate/migrations/routes/index.js
+++ b/packages/migrate/migrations/routes/index.js
@@ -1,8 +1,8 @@
 import fs from 'node:fs';
-import colors from 'kleur';
+import pc from 'picocolors';
 import path from 'node:path';
 import process from 'node:process';
-import prompts from 'prompts';
+import * as p from '@clack/prompts';
 import glob from 'tiny-glob/sync.js';
 import { pathToFileURL } from 'node:url';
 import { migrate_scripts } from './migrate_scripts/index.js';
@@ -10,7 +10,7 @@ import { migrate_page } from './migrate_page_js/index.js';
 import { migrate_page_server } from './migrate_page_server/index.js';
 import { migrate_server } from './migrate_server/index.js';
 import { adjust_imports, task } from './utils.js';
-import { bail, relative, move_file, check_git } from '../../utils.js';
+import { bail, relative, move_file, check_git, migration_succeeded } from '../../utils.js';
 
 export async function migrate() {
 	if (!fs.existsSync('svelte.config.js')) {
@@ -56,18 +56,16 @@ export async function migrate() {
 		}
 	}
 
-	console.log(colors.bold().yellow('\nThis will overwrite files in the current directory!\n'));
+	p.log.warning(pc.bold(pc.yellow('This will overwrite files in the current directory!')));
 
 	const use_git = check_git();
 
-	const response = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const response = await p.confirm({
 		message: 'Continue?',
-		initial: false
+		initialValue: false
 	});
 
-	if (!response.value) {
+	if (p.isCancel(response) || !response) {
 		process.exit(1);
 	}
 
@@ -185,27 +183,17 @@ export async function migrate() {
 		}
 	}
 
-	console.log(colors.bold().green('✔ Your project has been migrated'));
-
-	console.log('\nRecommended next steps:\n');
-
-	const cyan = colors.bold().cyan;
+	/** @type {(s: string) => string} */
+	const cyan = (s) => pc.bold(pc.cyan(s));
 
 	const tasks = [
 		use_git && cyan('git commit -m "svelte-migrate: renamed files"'),
 		'Review the migration guide at https://github.com/sveltejs/kit/discussions/5774',
 		`Search codebase for ${cyan('"@migration"')} and manually complete migration tasks`,
 		use_git && cyan('git add -A'),
-		use_git && cyan('git commit -m "svelte-migrate: updated files"')
+		use_git && cyan('git commit -m "svelte-migrate: updated files"'),
+		use_git && `Run ${cyan('git diff')} to review changes.`
 	].filter(Boolean);
 
-	tasks.forEach((task, i) => {
-		console.log(`  ${i + 1}: ${task}`);
-	});
-
-	console.log('');
-
-	if (use_git) {
-		console.log(`Run ${cyan('git diff')} to review changes.\n`);
-	}
+	migration_succeeded(tasks);
 }
diff --git a/packages/migrate/migrations/self-closing-tags/index.js b/packages/migrate/migrations/self-closing-tags/index.js
index ced6ca3..d724f2f 100644
--- a/packages/migrate/migrations/self-closing-tags/index.js
+++ b/packages/migrate/migrations/self-closing-tags/index.js
@@ -1,33 +1,32 @@
-import colors from 'kleur';
+import pc from 'picocolors';
 import fs from 'node:fs';
 import process from 'node:process';
-import prompts from 'prompts';
+import * as p from '@clack/prompts';
 import glob from 'tiny-glob/sync.js';
 import { remove_self_closing_tags } from './migrate.js';
 import { pathToFileURL } from 'node:url';
 import { resolve } from 'import-meta-resolve';
+import { migration_succeeded } from '../../utils.js';
 
 export async function migrate() {
 	let compiler;
 	try {
 		compiler = await import_from_cwd('svelte/compiler');
 	} catch {
-		console.log(colors.bold().red('❌ Could not find a local Svelte installation.'));
+		p.log.error(pc.bold(pc.red('❌ Could not find a local Svelte installation.')));
 		return;
 	}
 
-	console.log(
-		colors.bold().yellow('\nThis will update .svelte files inside the current directory\n')
+	p.log.warning(
+		pc.bold(pc.yellow('\nThis will update .svelte files inside the current directory\n'))
 	);
 
-	const response = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const response = await p.confirm({
 		message: 'Continue?',
-		initial: false
+		initialValue: false
 	});
 
-	if (!response.value) {
+	if (p.isCancel(response) || !response) {
 		process.exit(1);
 	}
 
@@ -44,8 +43,9 @@ export async function migrate() {
 		}
 	}
 
-	console.log(colors.bold().green('✔ Your project has been updated'));
-	console.log('  If using Prettier, please upgrade to the latest prettier-plugin-svelte version');
+	const tasks = ['If using Prettier, please upgrade to the latest prettier-plugin-svelte version'];
+
+	migration_succeeded(tasks);
 }
 
 /** @param {string} name */
diff --git a/packages/migrate/migrations/svelte-4/index.js b/packages/migrate/migrations/svelte-4/index.js
index 4fea517..4bab431 100644
--- a/packages/migrate/migrations/svelte-4/index.js
+++ b/packages/migrate/migrations/svelte-4/index.js
@@ -1,9 +1,15 @@
-import colors from 'kleur';
+import pc from 'picocolors';
 import fs from 'node:fs';
 import process from 'node:process';
-import prompts from 'prompts';
+import * as p from '@clack/prompts';
 import glob from 'tiny-glob/sync.js';
-import { bail, check_git, update_js_file, update_svelte_file } from '../../utils.js';
+import {
+	bail,
+	check_git,
+	migration_succeeded,
+	update_js_file,
+	update_svelte_file
+} from '../../utils.js';
 import { transform_code, transform_svelte_code, update_pkg_json } from './migrate.js';
 
 export async function migrate() {
@@ -11,33 +17,30 @@ export async function migrate() {
 		bail('Please re-run this script in a directory with a package.json');
 	}
 
-	console.log(
-		colors
-			.bold()
-			.yellow(
-				'\nThis will update files in the current directory\n' +
-					"If you're inside a monorepo, don't run this in the root directory, rather run it in all projects independently.\n"
+	p.log.warning(
+		pc.bold(pc.yellow('This will update files in the current directory.')) +
+			'\n' +
+			pc.bold(
+				pc.yellow(
+					"If you're inside a monorepo, don't run this in the root directory, rather run it in all projects independently."
+				)
 			)
 	);
 
 	const use_git = check_git();
 
-	const response = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const response = await p.confirm({
 		message: 'Continue?',
-		initial: false
+		initialValue: false
 	});
 
-	if (!response.value) {
+	if (p.isCancel(response) || !response) {
 		process.exit(1);
 	}
 
-	const folders = await prompts({
-		type: 'multiselect',
-		name: 'value',
+	const folders = await p.multiselect({
 		message: 'Which folders should be migrated?',
-		choices: fs
+		options: fs
 			.readdirSync('.')
 			.filter(
 				(dir) => fs.statSync(dir).isDirectory() && dir !== 'node_modules' && !dir.startsWith('.')
@@ -45,18 +48,20 @@ export async function migrate() {
 			.map((dir) => ({ title: dir, value: dir, selected: true }))
 	});
 
-	if (!folders.value?.length) {
+	if (p.isCancel(folders) || !folders?.length) {
 		process.exit(1);
 	}
 
-	const migrate_transition = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const migrate_transition = await p.confirm({
 		message:
 			'Add the `|global` modifier to currently global transitions for backwards compatibility? More info at https://svelte.dev/docs/svelte/v4-migration-guide#transitions-are-local-by-default',
-		initial: true
+		initialValue: true
 	});
 
+	if (p.isCancel(migrate_transition)) {
+		process.exit(1);
+	}
+
 	update_pkg_json();
 
 	// const { default: config } = fs.existsSync('svelte.config.js')
@@ -68,8 +73,8 @@ export async function migrate() {
 		'.svelte'
 	];
 	const extensions = [...svelte_extensions, '.ts', '.js'];
-	// For some reason {folders.value.join(',')} as part of the glob doesn't work and returns less files
-	const files = folders.value.flatMap(
+	// For some reason {folders.join(',')} as part of the glob doesn't work and returns less files
+	const files = folders.flatMap(
 		/** @param {string} folder */ (folder) =>
 			glob(`${folder}/**`, { filesOnly: true, dot: true })
 				.map((file) => file.replace(/\\/g, '/'))
@@ -80,7 +85,7 @@ export async function migrate() {
 		if (extensions.some((ext) => file.endsWith(ext))) {
 			if (svelte_extensions.some((ext) => file.endsWith(ext))) {
 				update_svelte_file(file, transform_code, (code) =>
-					transform_svelte_code(code, migrate_transition.value)
+					transform_svelte_code(code, migrate_transition)
 				);
 			} else {
 				update_js_file(file, transform_code);
@@ -88,25 +93,15 @@ export async function migrate() {
 		}
 	}
 
-	console.log(colors.bold().green('✔ Your project has been migrated'));
-
-	console.log('\nRecommended next steps:\n');
-
-	const cyan = colors.bold().cyan;
+	/** @type {(s: string) => string} */
+	const cyan = (s) => pc.bold(pc.cyan(s));
 
 	const tasks = [
 		use_git && cyan('git commit -m "migration to Svelte 4"'),
 		'Review the migration guide at https://svelte.dev/docs/svelte/v4-migration-guide',
-		'Read the updated docs at https://svelte.dev/docs/svelte'
+		'Read the updated docs at https://svelte.dev/docs/svelte',
+		use_git && `Run ${cyan('git diff')} to review changes.`
 	].filter(Boolean);
 
-	tasks.forEach((task, i) => {
-		console.log(`  ${i + 1}: ${task}`);
-	});
-
-	console.log('');
-
-	if (use_git) {
-		console.log(`Run ${cyan('git diff')} to review changes.\n`);
-	}
+	migration_succeeded(tasks);
 }
diff --git a/packages/migrate/migrations/svelte-5/index.js b/packages/migrate/migrations/svelte-5/index.js
index 7ba620f..92a1dfa 100644
--- a/packages/migrate/migrations/svelte-5/index.js
+++ b/packages/migrate/migrations/svelte-5/index.js
@@ -1,14 +1,20 @@
 import { resolve } from 'import-meta-resolve';
-import colors from 'kleur';
+import pc from 'picocolors';
 import { execSync } from 'node:child_process';
 import process from 'node:process';
 import fs from 'node:fs';
 import { dirname } from 'node:path';
 import { fileURLToPath, pathToFileURL } from 'node:url';
-import prompts from 'prompts';
+import * as p from '@clack/prompts';
 import semver from 'semver';
 import glob from 'tiny-glob/sync.js';
-import { bail, check_git, update_js_file, update_svelte_file } from '../../utils.js';
+import {
+	bail,
+	check_git,
+	migration_succeeded,
+	update_js_file,
+	update_svelte_file
+} from '../../utils.js';
 import { migrate as migrate_svelte_4 } from '../svelte-4/index.js';
 import { migrate as migrate_sveltekit_2 } from '../sveltekit-2/index.js';
 import { transform_module_code, transform_svelte_code, update_pkg_json } from './migrate.js';
@@ -22,29 +28,27 @@ export async function migrate() {
 
 	const svelte_dep = pkg.devDependencies?.svelte ?? pkg.dependencies?.svelte;
 	if (svelte_dep && semver.validRange(svelte_dep) && semver.gtr('4.0.0', svelte_dep)) {
-		console.log(
-			colors
-				.bold()
-				.yellow(
-					'\nDetected Svelte 3. You need to upgrade to Svelte version 4 first (`npx sv migrate svelte-4`).\n'
+		p.log.warning(
+			pc.bold(
+				pc.yellow(
+					'Detected Svelte 3. You need to upgrade to Svelte version 4 first (`npx sv migrate svelte-4`).'
 				)
+			)
 		);
-		const response = await prompts({
-			type: 'confirm',
-			name: 'value',
+		const response = await p.confirm({
 			message: 'Run svelte-4 migration now?',
-			initial: false
+			initialValue: false
 		});
-		if (!response.value) {
+		if (p.isCancel(response) || !response) {
 			process.exit(1);
 		} else {
 			await migrate_svelte_4();
-			console.log(
-				colors
-					.bold()
-					.green(
-						'svelte-4 migration complete. Check that everything is ok, then run `npx sv migrate svelte-5` again to continue the Svelte 5 migration.\n'
+			p.log.success(
+				pc.bold(
+					pc.green(
+						'svelte-4 migration complete. Check that everything is ok, then run `npx sv migrate svelte-5` again to continue the Svelte 5 migration.'
 					)
+				)
 			);
 			process.exit(0);
 		}
@@ -52,29 +56,27 @@ export async function migrate() {
 
 	const kit_dep = pkg.devDependencies?.['@sveltejs/kit'] ?? pkg.dependencies?.['@sveltejs/kit'];
 	if (kit_dep && semver.validRange(kit_dep) && semver.gtr('2.0.0', kit_dep)) {
-		console.log(
-			colors
-				.bold()
-				.yellow(
-					'\nDetected SvelteKit 1. You need to upgrade to SvelteKit version 2 first (`npx sv migrate sveltekit-2`).\n'
+		p.log.warning(
+			pc.bold(
+				pc.yellow(
+					'Detected SvelteKit 1. You need to upgrade to SvelteKit version 2 first (`npx sv migrate sveltekit-2`).'
 				)
+			)
 		);
-		const response = await prompts({
-			type: 'confirm',
-			name: 'value',
+		const response = await p.confirm({
 			message: 'Run sveltekit-2 migration now?',
-			initial: false
+			initialValue: false
 		});
-		if (!response.value) {
+		if (p.isCancel(response) || !response) {
 			process.exit(1);
 		} else {
 			await migrate_sveltekit_2();
-			console.log(
-				colors
-					.bold()
-					.green(
-						'sveltekit-2 migration complete. Check that everything is ok, then run `npx sv migrate svelte-5` again to continue the Svelte 5 migration.\n'
+			p.log.success(
+				pc.bold(
+					pc.green(
+						'sveltekit-2 migration complete. Check that everything is ok, then run `npx sv migrate svelte-5` again to continue the Svelte 5 migration.'
 					)
+				)
 			);
 			process.exit(0);
 		}
@@ -95,83 +97,80 @@ export async function migrate() {
 		}
 	} catch (e) {
 		console.log(e);
-		console.log(
-			colors
-				.bold()
-				.red(
+		p.log.error(
+			pc.bold(
+				pc.red(
 					'❌ Could not install Svelte. Manually bump the dependency to version 5 in your package.json, install it, then try again.'
 				)
+			)
 		);
 		return;
 	}
 
-	console.log(
-		colors
-			.bold()
-			.yellow(
-				'\nThis will update files in the current directory\n' +
-					"If you're inside a monorepo, don't run this in the root directory, rather run it in all projects independently.\n"
+	p.log.warning(
+		pc.bold(pc.yellow('This will update files in the current directory.')) +
+			'\n' +
+			pc.bold(
+				pc.yellow(
+					"If you're inside a monorepo, don't run this in the root directory, rather run it in all projects independently."
+				)
 			)
 	);
 
 	const use_git = check_git();
 
-	const response = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const response = await p.confirm({
 		message: 'Continue?',
-		initial: false
+		initialValue: false
 	});
 
-	if (!response.value) {
+	if (p.isCancel(response) || !response) {
 		process.exit(1);
 	}
 
-	const folders = await prompts({
-		type: 'multiselect',
-		name: 'value',
+	const dirs = fs
+		.readdirSync('.')
+		.filter(
+			(dir) => fs.statSync(dir).isDirectory() && dir !== 'node_modules' && !dir.startsWith('.')
+		);
+
+	let folders = await p.multiselect({
 		message: 'Which folders should be migrated?',
-		choices: fs
-			.readdirSync('.')
-			.filter(
-				(dir) => fs.statSync(dir).isDirectory() && dir !== 'node_modules' && !dir.startsWith('.')
-			)
-			.map((dir) => ({ title: dir, value: dir, selected: true }))
+		options: dirs
+			.map((dir) => ({ label: dir, value: dir }))
 			.concat([
 				{
-					title: 'custom (overrides selection, allows to specify sub folders)',
-					value: ',', // a value that definitely isn't a valid folder name so it cannot clash
-					selected: false
+					label: 'custom (overrides selection, allows to specify sub folders)',
+					value: ',' // a value that definitely isn't a valid folder name so it cannot clash
 				}
-			])
+			]),
+		initialValues: dirs
 	});
 
-	if (!folders.value?.length) {
+	if (p.isCancel(folders) || !folders?.length) {
 		process.exit(1);
 	}
 
-	if (folders.value.includes(',')) {
-		const custom = await prompts({
-			type: 'list',
-			name: 'value',
+	if (folders.includes(',')) {
+		const custom = await p.text({
 			message: 'Specify folder paths (comma separated)'
 		});
 
-		if (!custom.value) {
+		if (p.isCancel(custom) || !custom) {
 			process.exit(1);
 		}
 
-		folders.value = custom.value.map((/** @type {string} */ folder) => (folder = folder.trim()));
+		folders = custom.split(',').map((/** @type {string} */ folder) => (folder = folder.trim()));
 	}
 
-	const do_migration = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const do_migration = await p.confirm({
 		message:
 			'Do you want to use the migration tool to convert your Svelte components to the new syntax? (You can also do this per component or sub path later)',
-		initial: true
+		initialValue: true
 	});
 
+	if (p.isCancel(do_migration)) process.exit(1);
+
 	update_pkg_json();
 
 	const use_ts = fs.existsSync('tsconfig.json');
@@ -186,7 +185,7 @@ export async function migrate() {
 	];
 	const extensions = [...svelte_extensions, '.ts', '.js'];
 	// For some reason {folders.value.join(',')} as part of the glob doesn't work and returns less files
-	const files = folders.value.flatMap(
+	const files = folders.flatMap(
 		/** @param {string} folder */ (folder) =>
 			glob(`${folder}/**`, { filesOnly: true, dot: true })
 				.map((file) => file.replace(/\\/g, '/'))
@@ -196,7 +195,7 @@ export async function migrate() {
 	for (const file of files) {
 		if (extensions.some((ext) => file.endsWith(ext))) {
 			if (svelte_extensions.some((ext) => file.endsWith(ext))) {
-				if (do_migration.value) {
+				if (do_migration) {
 					update_svelte_file(file, transform_module_code, (code) =>
 						transform_svelte_code(code, migrate, { filename: file, use_ts })
 					);
@@ -207,28 +206,18 @@ export async function migrate() {
 		}
 	}
 
-	console.log(colors.bold().green('✔ Your project has been migrated'));
-
-	console.log('\nRecommended next steps:\n');
-
-	const cyan = colors.bold().cyan;
+	/** @type {(s: string) => string} */
+	const cyan = (s) => pc.bold(pc.cyan(s));
 
 	const tasks = [
 		"install the updated dependencies ('npm i' / 'pnpm i' / etc) " +
 			'(note that there may be peer dependency issues when not all your libraries officially support Svelte 5 yet. In this case try installing with the --force option)',
 		use_git && cyan('git commit -m "migration to Svelte 5"'),
-		'Review the migration guide at https://svelte.dev/docs/svelte/v5-migration-guide'
+		'Review the migration guide at https://svelte.dev/docs/svelte/v5-migration-guide',
+		`Run ${cyan('git diff')} to review changes.`
 	].filter(Boolean);
 
-	tasks.forEach((task, i) => {
-		console.log(`  ${i + 1}: ${task}`);
-	});
-
-	console.log('');
-
-	if (use_git) {
-		console.log(`Run ${cyan('git diff')} to review changes.\n`);
-	}
+	migration_succeeded(tasks);
 }
 
 /** @param {string} name */
diff --git a/packages/migrate/migrations/sveltekit-2/index.js b/packages/migrate/migrations/sveltekit-2/index.js
index c62442a..466233d 100644
--- a/packages/migrate/migrations/sveltekit-2/index.js
+++ b/packages/migrate/migrations/sveltekit-2/index.js
@@ -1,12 +1,13 @@
-import colors from 'kleur';
+import pc from 'picocolors';
 import fs from 'node:fs';
 import process from 'node:process';
-import prompts from 'prompts';
+import * as p from '@clack/prompts';
 import semver from 'semver';
 import glob from 'tiny-glob/sync.js';
 import {
 	bail,
 	check_git,
+	migration_succeeded,
 	update_js_file,
 	update_svelte_file,
 	update_tsconfig
@@ -28,25 +29,24 @@ export async function migrate() {
 		bail('Please re-run this script in a directory with a svelte.config.js');
 	}
 
-	console.log(
-		colors
-			.bold()
-			.yellow(
-				'\nThis will update files in the current directory\n' +
-					"If you're inside a monorepo, run this in individual project directories rather than the workspace root.\n"
+	p.log.warning(
+		pc.bold(pc.yellow('This will update files in the current directory.')) +
+			'\n' +
+			pc.bold(
+				pc.yellow(
+					"If you're inside a monorepo, don't run this in the root directory, rather run it in all projects independently."
+				)
 			)
 	);
 
 	const use_git = check_git();
 
-	const response = await prompts({
-		type: 'confirm',
-		name: 'value',
+	const response = await p.confirm({
 		message: 'Continue?',
-		initial: false
+		initialValue: false
 	});
 
-	if (!response.value) {
+	if (p.isCancel(response) || !response) {
 		process.exit(1);
 	}
 
@@ -57,45 +57,37 @@ export async function migrate() {
 	}
 
 	if (semver.validRange(svelte_dep) && semver.gtr('4.0.0', svelte_dep)) {
-		console.log(
-			colors
-				.bold()
-				.yellow(
-					'\nSvelteKit 2 requires Svelte 4 or newer. We recommend running the `svelte-4` migration first (`npx sv migrate svelte-4`).\n'
+		p.log.warning(
+			pc.bold(
+				pc.yellow(
+					'SvelteKit 2 requires Svelte 4 or newer. We recommend running the `svelte-4` migration first (`npx sv migrate svelte-4`).'
 				)
+			)
 		);
-		const response = await prompts({
-			type: 'confirm',
-			name: 'value',
+		const response = await p.confirm({
 			message: 'Run `svelte-4` migration now?',
-			initial: false
+			initialValue: false
 		});
-		if (!response.value) {
+		if (p.isCancel(response) || !response) {
 			process.exit(1);
 		} else {
 			await migrate_svelte_4();
-			console.log(
-				colors
-					.bold()
-					.green('`svelte-4` migration complete. Continue with `sveltekit-2` migration?\n')
+			p.log.success(
+				pc.bold(pc.green('`svelte-4` migration complete. Continue with `sveltekit-2` migration?\n'))
 			);
-			const response = await prompts({
-				type: 'confirm',
-				name: 'value',
+			const response = await p.confirm({
 				message: 'Continue?',
-				initial: false
+				initialValue: false
 			});
-			if (!response.value) {
+			if (p.isCancel(response) || !response) {
 				process.exit(1);
 			}
 		}
 	}
 
-	const folders = await prompts({
-		type: 'multiselect',
-		name: 'value',
+	const folders = await p.multiselect({
 		message: 'Which folders should be migrated?',
-		choices: fs
+		options: fs
 			.readdirSync('.')
 			.filter(
 				(dir) =>
@@ -107,7 +99,7 @@ export async function migrate() {
 			.map((dir) => ({ title: dir, value: dir, selected: dir === 'src' }))
 	});
 
-	if (!folders.value?.length) {
+	if (p.isCancel(folders) || !folders?.length) {
 		process.exit(1);
 	}
 
@@ -124,8 +116,8 @@ export async function migrate() {
 		'.svelte'
 	];
 	const extensions = [...svelte_extensions, '.ts', '.js'];
-	// For some reason {folders.value.join(',')} as part of the glob doesn't work and returns less files
-	const files = folders.value.flatMap(
+	// For some reason {folders.join(',')} as part of the glob doesn't work and returns less files
+	const files = folders.flatMap(
 		/** @param {string} folder */ (folder) =>
 			glob(`${folder}/**`, { filesOnly: true, dot: true })
 				.map((file) => file.replace(/\\/g, '/'))
@@ -142,26 +134,16 @@ export async function migrate() {
 		}
 	}
 
-	console.log(colors.bold().green('✔ Your project has been migrated'));
-
-	console.log('\nRecommended next steps:\n');
-
-	const cyan = colors.bold().cyan;
+	/** @type {(s: string) => string} */
+	const cyan = (s) => pc.bold(pc.cyan(s));
 
 	const tasks = [
 		'Run npm install (or the corresponding installation command of your package manager)',
 		use_git && cyan('git commit -m "migration to SvelteKit 2"'),
 		'Review the migration guide at https://svelte.dev/docs/kit/migrating-to-sveltekit-2',
-		'Read the updated docs at https://svelte.dev/docs/kit'
+		'Read the updated docs at https://svelte.dev/docs/kit',
+		use_git && `Run ${cyan('git diff')} to review changes.`
 	].filter(Boolean);
 
-	tasks.forEach((task, i) => {
-		console.log(`  ${i + 1}: ${task}`);
-	});
-
-	console.log('');
-
-	if (use_git) {
-		console.log(`Run ${cyan('git diff')} to review changes.\n`);
-	}
+	migration_succeeded(tasks);
 }
diff --git a/packages/migrate/package.json b/packages/migrate/package.json
index a789f88..c5a49e9 100644
--- a/packages/migrate/package.json
+++ b/packages/migrate/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "svelte-migrate",
-	"version": "1.8.0",
+	"version": "1.9.0",
 	"type": "module",
 	"description": "A CLI for migrating Svelte(Kit) codebases",
 	"license": "MIT",
@@ -27,10 +27,10 @@
 		"svelte-migrate": "./bin.js"
 	},
 	"dependencies": {
+		"@clack/prompts": "^0.9.0",
 		"import-meta-resolve": "^4.1.0",
-		"kleur": "^4.1.5",
 		"magic-string": "^0.30.15",
-		"prompts": "^2.4.2",
+		"picocolors": "^1.1.1",
 		"semver": "^7.6.3",
 		"tiny-glob": "^0.2.9",
 		"ts-morph": "^24.0.0",
diff --git a/packages/migrate/utils.js b/packages/migrate/utils.js
index 944461f..4fd0066 100644
--- a/packages/migrate/utils.js
+++ b/packages/migrate/utils.js
@@ -1,4 +1,5 @@
-import colors from 'kleur';
+import * as p from '@clack/prompts';
+import pc from 'picocolors';
 import MagicString from 'magic-string';
 import { execFileSync, execSync } from 'node:child_process';
 import fs from 'node:fs';
@@ -9,7 +10,7 @@ import ts from 'typescript';
 
 /** @param {string} message */
 export function bail(message) {
-	console.error(colors.bold().red(message));
+	p.log.error(pc.bold(pc.red(message)));
 	process.exit(1);
 }
 
@@ -152,15 +153,15 @@ export function check_git() {
 
 			if (status) {
 				const message =
-					'Your git working directory is dirty — we recommend committing your changes before running this migration.\n';
-				console.log(colors.bold().red(message));
+					'Your git working directory is dirty — we recommend committing your changes before running this migration.';
+				p.log.warning(pc.bold(pc.red(message)));
 			}
 		} catch {
 			// would be weird to have a .git folder if git is not installed,
 			// but always expect the unexpected
 			const message =
-				'Could not detect a git installation. If this is unexpected, please raise an issue: https://github.com/sveltejs/kit.\n';
-			console.log(colors.bold().red(message));
+				'Could not detect a git installation. If this is unexpected, please raise an issue: https://github.com/sveltejs/cli.\n';
+			p.log.warning(pc.bold(pc.red(message)));
 			use_git = false;
 		}
 	}
@@ -419,3 +420,25 @@ export function add_named_import(source, _import, method) {
 		});
 	}
 }
+
+/**
+ * @param {(string | false)[]} next_steps
+ */
+export function migration_succeeded(next_steps) {
+	p.log.success(pc.bold(pc.green('✔ Your project has been migrated')));
+
+	if (!next_steps || next_steps.length === 0) {
+		return;
+	}
+
+	/** @type {string[]} */
+	const messages = [];
+
+	next_steps.forEach((step, i) => {
+		if (!step) return;
+
+		messages.push(`${i + 1}: ${step}`);
+	});
+
+	p.note(messages.join('\n'), 'Recommended next steps:');
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a92d259..f543123 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,18 +14,6 @@ importers:
       '@playwright/test':
         specifier: ^1.49.1
         version: 1.49.1
-      '@rollup/plugin-commonjs':
-        specifier: ^28.0.2
-        version: 28.0.2(rollup@4.28.1)
-      '@rollup/plugin-dynamic-import-vars':
-        specifier: ^2.1.5
-        version: 2.1.5(rollup@4.28.1)
-      '@rollup/plugin-json':
-        specifier: ^6.1.0
-        version: 6.1.0(rollup@4.28.1)
-      '@rollup/plugin-node-resolve':
-        specifier: ^15.3.0
-        version: 15.3.0(rollup@4.28.1)
       '@sveltejs/create':
         specifier: workspace:*
         version: link:packages/create
@@ -56,15 +44,9 @@ importers:
       prettier-plugin-svelte:
         specifier: ^3.3.2
         version: 3.3.2(prettier@3.4.2)(svelte@5.12.0)
-      rollup:
-        specifier: ^4.28.1
-        version: 4.28.1
-      rollup-plugin-esbuild:
-        specifier: ^6.1.1
-        version: 6.1.1(esbuild@0.24.2)(rollup@4.28.1)
-      rollup-plugin-preserve-shebangs:
-        specifier: ^0.2.0
-        version: 0.2.0(rollup@4.28.1)
+      rolldown:
+        specifier: 1.0.0-beta.1
+        version: 1.0.0-beta.1(@babel/runtime@7.26.0)
       sv:
         specifier: workspace:*
         version: link:packages/cli
@@ -256,18 +238,18 @@ importers:
 
   packages/migrate:
     dependencies:
+      '@clack/prompts':
+        specifier: ^0.9.0
+        version: 0.9.0
       import-meta-resolve:
         specifier: ^4.1.0
         version: 4.1.0
-      kleur:
-        specifier: ^4.1.5
-        version: 4.1.5
       magic-string:
         specifier: ^0.30.15
         version: 0.30.17
-      prompts:
-        specifier: ^2.4.2
-        version: 2.4.2
+      picocolors:
+        specifier: ^1.1.1
+        version: 1.1.1
       semver:
         specifier: ^7.6.3
         version: 7.6.3
@@ -382,6 +364,21 @@ packages:
   '@changesets/write@0.3.2':
     resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==}
 
+  '@clack/core@0.4.0':
+    resolution: {integrity: sha512-YJCYBsyJfNDaTbvDUVSJ3SgSuPrcujarRgkJ5NLjexDZKvaOiVVJvAQYx8lIgG0qRT8ff0fPgqyBCVivanIZ+A==}
+
+  '@clack/prompts@0.9.0':
+    resolution: {integrity: sha512-nGsytiExgUr4FL0pR/LeqxA28nz3E0cW7eLTSh3Iod9TGrbBt8Y7BHbV3mmkNC4G0evdYyQ3ZsbiBkk7ektArA==}
+
+  '@emnapi/core@1.3.1':
+    resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==}
+
+  '@emnapi/runtime@1.3.1':
+    resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
+
+  '@emnapi/wasi-threads@1.0.1':
+    resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==}
+
   '@esbuild/aix-ppc64@0.24.2':
     resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
     engines: {node: '>=18'}
@@ -614,6 +611,9 @@ packages:
   '@manypkg/get-packages@1.1.3':
     resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==}
 
+  '@napi-rs/wasm-runtime@0.2.6':
+    resolution: {integrity: sha512-z8YVS3XszxFTO73iwvFDNpQIzdMmSDTP/mB3E/ucR37V3Sx57hSExcXyMoNwaucWxnsWf4xfbZv0iZ30jr0M4Q==}
+
   '@nodelib/fs.scandir@2.1.5':
     resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
     engines: {node: '>= 8'}
@@ -685,41 +685,65 @@ packages:
   '@polka/url@1.0.0-next.28':
     resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==}
 
-  '@rollup/plugin-commonjs@28.0.2':
-    resolution: {integrity: sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==}
-    engines: {node: '>=16.0.0 || 14 >= 14.17'}
-    peerDependencies:
-      rollup: ^2.68.0||^3.0.0||^4.0.0
-    peerDependenciesMeta:
-      rollup:
-        optional: true
+  '@rolldown/binding-darwin-arm64@1.0.0-beta.1':
+    resolution: {integrity: sha512-e4QpTp7eu61JilK958i21RK/HniwVLjZgfShqoQY1VM+KDYz90cNuopKQ3Z3oCkvyAN3xI8IaRhy02nlxdR/DA==}
+    cpu: [arm64]
+    os: [darwin]
 
-  '@rollup/plugin-dynamic-import-vars@2.1.5':
-    resolution: {integrity: sha512-Mymi24fd9hlRifdZV/jYIFj1dn99F34imiYu3KzlAcgBcRi3i9SucgW/VRo5SQ9K4NuQ7dCep6pFWgNyhRdFHQ==}
-    engines: {node: '>=14.0.0'}
-    peerDependencies:
-      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
-    peerDependenciesMeta:
-      rollup:
-        optional: true
+  '@rolldown/binding-darwin-x64@1.0.0-beta.1':
+    resolution: {integrity: sha512-+WHRLrogJl99EQ6HtYhy7EwIZ1wicD0RSX2T5mjfOM6AmPwPTXQ0n6MKOs1abU6ZyCj5Izlo6rLsao0h9FMUDA==}
+    cpu: [x64]
+    os: [darwin]
 
-  '@rollup/plugin-json@6.1.0':
-    resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==}
-    engines: {node: '>=14.0.0'}
-    peerDependencies:
-      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
-    peerDependenciesMeta:
-      rollup:
-        optional: true
+  '@rolldown/binding-freebsd-x64@1.0.0-beta.1':
+    resolution: {integrity: sha512-ZP9Q1q4IfvJ8dfWTHOF3cquNpAKuQQ+kZJQTxo85fGnKqtqMWFNouaBVd79pqCxU3w4oIjuZ8o55qNDomMTbVA==}
+    cpu: [x64]
+    os: [freebsd]
 
-  '@rollup/plugin-node-resolve@15.3.0':
-    resolution: {integrity: sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==}
-    engines: {node: '>=14.0.0'}
-    peerDependencies:
-      rollup: ^2.78.0||^3.0.0||^4.0.0
-    peerDependenciesMeta:
-      rollup:
-        optional: true
+  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.1':
+    resolution: {integrity: sha512-B/R4Vt8f8z/WmW9Y9NMgA+t5bCfRLmgZohs5mWf8KoD5FRlpvJtCo/SnD7fEg9npHEP5A28+Cikiyd7aCcKPSA==}
+    cpu: [arm]
+    os: [linux]
+
+  '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.1':
+    resolution: {integrity: sha512-xkGD+YLH+vQZiqxKEsXe8xS/owQXkyARaNB9NfFrAacLoNIRZM5UEZGNKxXyRWd1kSEkYkJ3/WiqvGGCcqUg1A==}
+    cpu: [arm64]
+    os: [linux]
+
+  '@rolldown/binding-linux-arm64-musl@1.0.0-beta.1':
+    resolution: {integrity: sha512-Ey2UxKFL74JuWpdNl9stpV0kxHZIgCWCEUnDnpQ1hcBwO9KwDM5qicLtXfsjozD6vt+xzbrL2D/uTrziYZ7IDQ==}
+    cpu: [arm64]
+    os: [linux]
+
+  '@rolldown/binding-linux-x64-gnu@1.0.0-beta.1':
+    resolution: {integrity: sha512-a8QP35x/3mggWqCpFtaF3/PbWl5P9QKpP/muk3iMPgzrXto8zPsEl3imsP3EBh4KwanBVHIf8pEkBQ+/7iMTgQ==}
+    cpu: [x64]
+    os: [linux]
+
+  '@rolldown/binding-linux-x64-musl@1.0.0-beta.1':
+    resolution: {integrity: sha512-uIqKwnkZjTY8FmqGMaSjwtWlCdV88LV9bjdkv+mb7I+BBw+9cJlIQy0P8YnGEOEcnDPis/SiraCpkJ/eHYaSZw==}
+    cpu: [x64]
+    os: [linux]
+
+  '@rolldown/binding-wasm32-wasi@1.0.0-beta.1':
+    resolution: {integrity: sha512-RB+gbhwZtTbKbvHzUcaRFva2ONCUTuxDEb/b3/rd3O82OTPUZzOY24mqreiXH1XG09p6WFXSE8dzUrN120Q29w==}
+    engines: {node: '>=14.21.3'}
+    cpu: [wasm32]
+
+  '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1':
+    resolution: {integrity: sha512-NSccQD7+9vhEfDMc8HyODuUU1jLYEsEiICc1zwmbeg0FXx1pwpFpZZQby4bAMnK2obav7D9FfsruYWodhNdIqQ==}
+    cpu: [arm64]
+    os: [win32]
+
+  '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.1':
+    resolution: {integrity: sha512-bUQOqqHfqgX9gHGZFGVYQRtc4+9diFDS/f85dKrzzUg7MF91ZU9mJUoemL4eyyj3B83N3FlHZtAPvDX3N2Zz8A==}
+    cpu: [ia32]
+    os: [win32]
+
+  '@rolldown/binding-win32-x64-msvc@1.0.0-beta.1':
+    resolution: {integrity: sha512-k8Ld05OlxkzR/+Ob8+IESaZ4uFcgLwbbwtUZLoryn3S6lCogkclcN/4m1wo/PyWtUAWF5mdz83SrkRL8dS4AqA==}
+    cpu: [x64]
+    os: [win32]
 
   '@rollup/pluginutils@5.1.3':
     resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==}
@@ -849,6 +873,9 @@ packages:
   '@ts-morph/common@0.25.0':
     resolution: {integrity: sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==}
 
+  '@tybys/wasm-util@0.9.0':
+    resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
+
   '@types/degit@2.8.6':
     resolution: {integrity: sha512-y0M7sqzsnHB6cvAeTCBPrCQNQiZe8U4qdzf8uBVmOWYap5MMTN/gB2iEqrIqFiYcsyvP74GnGD5tgsHttielFw==}
 
@@ -876,9 +903,6 @@ packages:
   '@types/ps-tree@1.1.6':
     resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==}
 
-  '@types/resolve@1.20.2':
-    resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
-
   '@types/semver@7.5.8':
     resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
 
@@ -1032,10 +1056,6 @@ packages:
     resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
     engines: {node: '>=4'}
 
-  astring@1.9.0:
-    resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
-    hasBin: true
-
   axobject-query@4.1.0:
     resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
     engines: {node: '>= 0.4'}
@@ -1123,9 +1143,6 @@ packages:
     resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
     engines: {node: '>= 6'}
 
-  commondir@1.0.1:
-    resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
-
   concat-map@0.0.1:
     resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
 
@@ -1173,10 +1190,6 @@ packages:
   deep-is@0.1.4:
     resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
 
-  deepmerge@4.3.1:
-    resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
-    engines: {node: '>=0.10.0'}
-
   degit@2.8.4:
     resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==}
     engines: {node: '>=8.0.0'}
@@ -1451,9 +1464,6 @@ packages:
     engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
     os: [darwin]
 
-  function-bind@1.1.2:
-    resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
-
   get-stdin@9.0.0:
     resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==}
     engines: {node: '>=12'}
@@ -1508,10 +1518,6 @@ packages:
     resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
     engines: {node: '>=8'}
 
-  hasown@2.0.2:
-    resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
-    engines: {node: '>= 0.4'}
-
   htmlparser2@9.1.0:
     resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
 
@@ -1537,10 +1543,6 @@ packages:
     resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
     engines: {node: '>=0.8.19'}
 
-  is-core-module@2.16.0:
-    resolution: {integrity: sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==}
-    engines: {node: '>= 0.4'}
-
   is-extglob@2.1.1:
     resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
     engines: {node: '>=0.10.0'}
@@ -1553,9 +1555,6 @@ packages:
     resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
     engines: {node: '>=0.10.0'}
 
-  is-module@1.0.0:
-    resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
-
   is-number@7.0.0:
     resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
     engines: {node: '>=0.12.0'}
@@ -1564,9 +1563,6 @@ packages:
     resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
     engines: {node: '>=12'}
 
-  is-reference@1.2.1:
-    resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
-
   is-reference@3.0.3:
     resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==}
 
@@ -1615,10 +1611,6 @@ packages:
     resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
     engines: {node: '>=6'}
 
-  kleur@4.1.5:
-    resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
-    engines: {node: '>=6'}
-
   known-css-properties@0.35.0:
     resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==}
 
@@ -1656,9 +1648,6 @@ packages:
   lru-cache@10.4.3:
     resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
 
-  magic-string@0.25.9:
-    resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
-
   magic-string@0.30.17:
     resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
 
@@ -1788,9 +1777,6 @@ packages:
     resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
     engines: {node: '>=8'}
 
-  path-parse@1.0.7:
-    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
-
   path-scurry@1.11.1:
     resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
     engines: {node: '>=16 || 14 >=14.18'}
@@ -1901,10 +1887,6 @@ packages:
     engines: {node: '>=14'}
     hasBin: true
 
-  prompts@2.4.2:
-    resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
-    engines: {node: '>= 6'}
-
   ps-tree@1.2.0:
     resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
     engines: {node: '>= 0.10'}
@@ -1945,25 +1927,18 @@ packages:
   resolve-pkg-maps@1.0.0:
     resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
 
-  resolve@1.22.9:
-    resolution: {integrity: sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==}
-    hasBin: true
-
   reusify@1.0.4:
     resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
     engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
 
-  rollup-plugin-esbuild@6.1.1:
-    resolution: {integrity: sha512-CehMY9FAqJD5OUaE/Mi1r5z0kNeYxItmRO2zG4Qnv2qWKF09J2lTy5GUzjJR354ZPrLkCj4fiBN41lo8PzBUhw==}
-    engines: {node: '>=14.18.0'}
-    peerDependencies:
-      esbuild: '>=0.18.0'
-      rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
-
-  rollup-plugin-preserve-shebangs@0.2.0:
-    resolution: {integrity: sha512-OEyTIfZwUJ7yUAVAbegac/bNvp1WJzgZcQNCFprWX42wwwOqlJwrev9lUmzZdYVgCWct+03xUPvZg4RfgkM9oQ==}
+  rolldown@1.0.0-beta.1:
+    resolution: {integrity: sha512-19B2HoY3zcR7Um+zVDOvV1gQ1d6acUIouCUMGxvlZ/0kTjcMSFr8tuLWmRRYIV7y1mrgPbJRd1cPFVd4p1l8nQ==}
+    hasBin: true
     peerDependencies:
-      rollup: '*'
+      '@babel/runtime': '>=7'
+    peerDependenciesMeta:
+      '@babel/runtime':
+        optional: true
 
   rollup@4.28.1:
     resolution: {integrity: sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==}
@@ -2025,10 +2000,6 @@ packages:
     resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
     engines: {node: '>=0.10.0'}
 
-  sourcemap-codec@1.4.8:
-    resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
-    deprecated: Please use @jridgewell/sourcemap-codec instead
-
   spawndamnit@3.0.1:
     resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==}
 
@@ -2083,10 +2054,6 @@ packages:
     resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
     engines: {node: '>=8'}
 
-  supports-preserve-symlinks-flag@1.0.0:
-    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
-    engines: {node: '>= 0.4'}
-
   svelte-eslint-parser@0.43.0:
     resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -2367,6 +2334,9 @@ packages:
   zimmerframe@1.1.2:
     resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
 
+  zod@3.24.1:
+    resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
+
 snapshots:
 
   '@ampproject/remapping@2.3.0':
@@ -2540,6 +2510,33 @@ snapshots:
       human-id: 1.0.2
       prettier: 2.8.8
 
+  '@clack/core@0.4.0':
+    dependencies:
+      picocolors: 1.1.1
+      sisteransi: 1.0.5
+
+  '@clack/prompts@0.9.0':
+    dependencies:
+      '@clack/core': 0.4.0
+      picocolors: 1.1.1
+      sisteransi: 1.0.5
+
+  '@emnapi/core@1.3.1':
+    dependencies:
+      '@emnapi/wasi-threads': 1.0.1
+      tslib: 2.8.1
+    optional: true
+
+  '@emnapi/runtime@1.3.1':
+    dependencies:
+      tslib: 2.8.1
+    optional: true
+
+  '@emnapi/wasi-threads@1.0.1':
+    dependencies:
+      tslib: 2.8.1
+    optional: true
+
   '@esbuild/aix-ppc64@0.24.2':
     optional: true
 
@@ -2711,6 +2708,13 @@ snapshots:
       globby: 11.1.0
       read-yaml-file: 1.1.0
 
+  '@napi-rs/wasm-runtime@0.2.6':
+    dependencies:
+      '@emnapi/core': 1.3.1
+      '@emnapi/runtime': 1.3.1
+      '@tybys/wasm-util': 0.9.0
+    optional: true
+
   '@nodelib/fs.scandir@2.1.5':
     dependencies:
       '@nodelib/fs.stat': 2.0.5
@@ -2760,43 +2764,43 @@ snapshots:
 
   '@polka/url@1.0.0-next.28': {}
 
-  '@rollup/plugin-commonjs@28.0.2(rollup@4.28.1)':
-    dependencies:
-      '@rollup/pluginutils': 5.1.3(rollup@4.28.1)
-      commondir: 1.0.1
-      estree-walker: 2.0.2
-      fdir: 6.4.3(picomatch@4.0.2)
-      is-reference: 1.2.1
-      magic-string: 0.30.17
-      picomatch: 4.0.2
-    optionalDependencies:
-      rollup: 4.28.1
+  '@rolldown/binding-darwin-arm64@1.0.0-beta.1':
+    optional: true
 
-  '@rollup/plugin-dynamic-import-vars@2.1.5(rollup@4.28.1)':
-    dependencies:
-      '@rollup/pluginutils': 5.1.3(rollup@4.28.1)
-      astring: 1.9.0
-      estree-walker: 2.0.2
-      fast-glob: 3.3.2
-      magic-string: 0.30.17
-    optionalDependencies:
-      rollup: 4.28.1
+  '@rolldown/binding-darwin-x64@1.0.0-beta.1':
+    optional: true
 
-  '@rollup/plugin-json@6.1.0(rollup@4.28.1)':
-    dependencies:
-      '@rollup/pluginutils': 5.1.3(rollup@4.28.1)
-    optionalDependencies:
-      rollup: 4.28.1
+  '@rolldown/binding-freebsd-x64@1.0.0-beta.1':
+    optional: true
 
-  '@rollup/plugin-node-resolve@15.3.0(rollup@4.28.1)':
+  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.1':
+    optional: true
+
+  '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.1':
+    optional: true
+
+  '@rolldown/binding-linux-arm64-musl@1.0.0-beta.1':
+    optional: true
+
+  '@rolldown/binding-linux-x64-gnu@1.0.0-beta.1':
+    optional: true
+
+  '@rolldown/binding-linux-x64-musl@1.0.0-beta.1':
+    optional: true
+
+  '@rolldown/binding-wasm32-wasi@1.0.0-beta.1':
     dependencies:
-      '@rollup/pluginutils': 5.1.3(rollup@4.28.1)
-      '@types/resolve': 1.20.2
-      deepmerge: 4.3.1
-      is-module: 1.0.0
-      resolve: 1.22.9
-    optionalDependencies:
-      rollup: 4.28.1
+      '@napi-rs/wasm-runtime': 0.2.6
+    optional: true
+
+  '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1':
+    optional: true
+
+  '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.1':
+    optional: true
+
+  '@rolldown/binding-win32-x64-msvc@1.0.0-beta.1':
+    optional: true
 
   '@rollup/pluginutils@5.1.3(rollup@4.28.1)':
     dependencies:
@@ -2893,6 +2897,11 @@ snapshots:
       path-browserify: 1.0.1
       tinyglobby: 0.2.10
 
+  '@tybys/wasm-util@0.9.0':
+    dependencies:
+      tslib: 2.8.1
+    optional: true
+
   '@types/degit@2.8.6': {}
 
   '@types/estree@1.0.6': {}
@@ -2918,8 +2927,6 @@ snapshots:
 
   '@types/ps-tree@1.1.6': {}
 
-  '@types/resolve@1.20.2': {}
-
   '@types/semver@7.5.8': {}
 
   '@types/tar-fs@2.0.4':
@@ -3106,8 +3113,6 @@ snapshots:
     dependencies:
       tslib: 2.8.1
 
-  astring@1.9.0: {}
-
   axobject-query@4.1.0: {}
 
   b4a@1.6.7: {}
@@ -3197,8 +3202,6 @@ snapshots:
 
   commander@4.1.1: {}
 
-  commondir@1.0.1: {}
-
   concat-map@0.0.1: {}
 
   cross-spawn@7.0.6:
@@ -3228,8 +3231,6 @@ snapshots:
 
   deep-is@0.1.4: {}
 
-  deepmerge@4.3.1: {}
-
   degit@2.8.4: {}
 
   detect-indent@6.1.0: {}
@@ -3555,8 +3556,6 @@ snapshots:
   fsevents@2.3.3:
     optional: true
 
-  function-bind@1.1.2: {}
-
   get-stdin@9.0.0: {}
 
   get-tsconfig@4.10.0:
@@ -3607,10 +3606,6 @@ snapshots:
 
   has-flag@4.0.0: {}
 
-  hasown@2.0.2:
-    dependencies:
-      function-bind: 1.1.2
-
   htmlparser2@9.1.0:
     dependencies:
       domelementtype: 2.3.0
@@ -3635,10 +3630,6 @@ snapshots:
 
   imurmurhash@0.1.4: {}
 
-  is-core-module@2.16.0:
-    dependencies:
-      hasown: 2.0.2
-
   is-extglob@2.1.1: {}
 
   is-fullwidth-code-point@3.0.0: {}
@@ -3647,16 +3638,10 @@ snapshots:
     dependencies:
       is-extglob: 2.1.1
 
-  is-module@1.0.0: {}
-
   is-number@7.0.0: {}
 
   is-plain-obj@4.1.0: {}
 
-  is-reference@1.2.1:
-    dependencies:
-      '@types/estree': 1.0.6
-
   is-reference@3.0.3:
     dependencies:
       '@types/estree': 1.0.6
@@ -3702,8 +3687,6 @@ snapshots:
 
   kleur@3.0.3: {}
 
-  kleur@4.1.5: {}
-
   known-css-properties@0.35.0: {}
 
   levn@0.4.1:
@@ -3733,10 +3716,6 @@ snapshots:
 
   lru-cache@10.4.3: {}
 
-  magic-string@0.25.9:
-    dependencies:
-      sourcemap-codec: 1.4.8
-
   magic-string@0.30.17:
     dependencies:
       '@jridgewell/sourcemap-codec': 1.5.0
@@ -3852,8 +3831,6 @@ snapshots:
 
   path-key@3.1.1: {}
 
-  path-parse@1.0.7: {}
-
   path-scurry@1.11.1:
     dependencies:
       lru-cache: 10.4.3
@@ -3937,11 +3914,6 @@ snapshots:
 
   prettier@3.4.2: {}
 
-  prompts@2.4.2:
-    dependencies:
-      kleur: 3.0.3
-      sisteransi: 1.0.5
-
   ps-tree@1.2.0:
     dependencies:
       event-stream: 3.3.4
@@ -3980,29 +3952,25 @@ snapshots:
 
   resolve-pkg-maps@1.0.0: {}
 
-  resolve@1.22.9:
-    dependencies:
-      is-core-module: 2.16.0
-      path-parse: 1.0.7
-      supports-preserve-symlinks-flag: 1.0.0
-
   reusify@1.0.4: {}
 
-  rollup-plugin-esbuild@6.1.1(esbuild@0.24.2)(rollup@4.28.1):
+  rolldown@1.0.0-beta.1(@babel/runtime@7.26.0):
     dependencies:
-      '@rollup/pluginutils': 5.1.3(rollup@4.28.1)
-      debug: 4.4.0
-      es-module-lexer: 1.6.0
-      esbuild: 0.24.2
-      get-tsconfig: 4.10.0
-      rollup: 4.28.1
-    transitivePeerDependencies:
-      - supports-color
-
-  rollup-plugin-preserve-shebangs@0.2.0(rollup@4.28.1):
-    dependencies:
-      magic-string: 0.25.9
-      rollup: 4.28.1
+      zod: 3.24.1
+    optionalDependencies:
+      '@babel/runtime': 7.26.0
+      '@rolldown/binding-darwin-arm64': 1.0.0-beta.1
+      '@rolldown/binding-darwin-x64': 1.0.0-beta.1
+      '@rolldown/binding-freebsd-x64': 1.0.0-beta.1
+      '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.1
+      '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.1
+      '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.1
+      '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.1
+      '@rolldown/binding-linux-x64-musl': 1.0.0-beta.1
+      '@rolldown/binding-wasm32-wasi': 1.0.0-beta.1
+      '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.1
+      '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.1
+      '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.1
 
   rollup@4.28.1:
     dependencies:
@@ -4076,8 +4044,6 @@ snapshots:
 
   source-map@0.6.1: {}
 
-  sourcemap-codec@1.4.8: {}
-
   spawndamnit@3.0.1:
     dependencies:
       cross-spawn: 7.0.6
@@ -4143,8 +4109,6 @@ snapshots:
     dependencies:
       has-flag: 4.0.0
 
-  supports-preserve-symlinks-flag@1.0.0: {}
-
   svelte-eslint-parser@0.43.0(svelte@5.12.0):
     dependencies:
       eslint-scope: 7.2.2
@@ -4430,3 +4394,5 @@ snapshots:
   yocto-queue@0.1.0: {}
 
   zimmerframe@1.1.2: {}
+
+  zod@3.24.1: {}
diff --git a/rollup.config.js b/rolldown.config.js
similarity index 79%
rename from rollup.config.js
rename to rolldown.config.js
index bc4f764..5d193af 100644
--- a/rollup.config.js
+++ b/rolldown.config.js
@@ -1,29 +1,23 @@
 // @ts-check
 import fs from 'node:fs';
 import path from 'node:path';
-import { nodeResolve } from '@rollup/plugin-node-resolve';
-import commonjs from '@rollup/plugin-commonjs';
-import json from '@rollup/plugin-json';
-import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
-import { preserveShebangs } from 'rollup-plugin-preserve-shebangs';
-import dts from 'unplugin-isolated-decl/rollup';
-import esbuild from 'rollup-plugin-esbuild';
+import dts from 'unplugin-isolated-decl/rolldown';
 import { buildTemplates } from '@sveltejs/create/build';
 import MagicString from 'magic-string';
 
-/** @import { Package } from "./packages/cli/commands/add/utils" */
-/** @import { Plugin, RollupOptions } from "rollup" */
+/** @import { Package } from "./packages/cli/commands/add/utils.ts" */
+/** @import { Plugin, RolldownOptions } from "rolldown" */
 /** @typedef {Package & { peerDependencies: Record<string, string> }} PackageJson */
 
 /**
  * @param {string} project
- * @returns {RollupOptions}
+ * @returns {RolldownOptions}
  */
 function getConfig(project) {
 	const projectRoot = `./packages/${project}`;
 	const outDir = `${projectRoot}/dist`;
 
-	/** @type {RollupOptions["input"]} */
+	/** @type {RolldownOptions["input"]} */
 	let inputs;
 
 	if (project === 'core') {
@@ -57,7 +51,7 @@ function getConfig(project) {
 	let buildCliTemplatesPlugin;
 	if (project === 'create') {
 		// This plugin is used to build the templates and place them inside the
-		// `dist` folder after every rollup build. This is necessary as we're
+		// `dist` folder after every rolldown build. This is necessary as we're
 		// clearing the output directory and thus also removes the template files
 		buildCliTemplatesPlugin = {
 			name: 'build-cli-templates',
@@ -104,6 +98,7 @@ function getConfig(project) {
 
 	return {
 		input: inputs,
+		platform: 'node',
 		output: {
 			dir: outDir,
 			format: 'esm',
@@ -111,28 +106,18 @@ function getConfig(project) {
 		},
 		external,
 		plugins: [
-			preserveShebangs(),
 			'exports' in pkg &&
 				dts({
 					include: project === 'cli' ? [`${projectRoot}/lib/*`] : undefined,
 					inputBase: project === 'cli' ? path.resolve(projectRoot, 'lib') : undefined
 				}),
-			esbuild(),
-			nodeResolve({ preferBuiltins: true, rootDir: projectRoot }),
-			commonjs(),
-			json(),
-			dynamicImportVars({
-				// since we're relying on the usage of standard dynamic imports for community addons, we need to
-				// prevent this plugin from transforming these cases
-				exclude: ['packages/cli/commands/add/fetch-packages.ts']
-			}),
 			buildCliTemplatesPlugin,
 			communityAddonIdsPlugin
 		]
 	};
 }
 
-/** @type {RollupOptions[]} */
+/** @type {RolldownOptions[]} */
 export default [
 	getConfig('clack-core'),
 	getConfig('clack-prompts'),
diff --git a/tsconfig.json b/tsconfig.json
index 43414d2..295f387 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,9 +5,9 @@
 		"**/core/tests/**",
 		"packages/create/templates/**",
 		"packages/create/shared/**",
-		// Ignoring the rollup config so that the imported plugins can resolve their types correctly
+		// Ignoring the rolldown config so that the imported plugins can resolve their types correctly
 		// (setting `moduleResolution: Node16` breaks them)
-		"rollup.config.js"
+		"rolldown.config.js"
 	],
 	"compilerOptions": {
 		"checkJs": true,


Test patch:
diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts
index 46f3f8c..9b2dc0a 100644
--- a/community-addon-template/tests/setup/suite.ts
+++ b/community-addon-template/tests/setup/suite.ts
@@ -3,7 +3,13 @@ import path from 'node:path';
 import { execSync } from 'node:child_process';
 import * as vitest from 'vitest';
 import { installAddon, type AddonMap, type OptionMap } from 'sv';
-import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/testing';
+import {
+	addPnpmBuildDependendencies,
+	createProject,
+	startPreview,
+	type CreateProject,
+	type ProjectVariant
+} from 'sv/testing';
 import { chromium, type Browser, type Page } from '@playwright/test';
 import { fileURLToPath } from 'node:url';
 
@@ -40,9 +46,18 @@ export function setupTest<Addons extends AddonMap>(addons: Addons) {
 		// creates a pnpm workspace in each addon dir
 		fs.writeFileSync(
 			path.resolve(cwd, testName, 'pnpm-workspace.yaml'),
-			`packages:\n  - '**/*'`,
+			"packages:\n  - '**/*'",
 			'utf8'
 		);
+
+		// creates a barebones package.json in each addon dir
+		fs.writeFileSync(
+			path.resolve(cwd, testName, 'package.json'),
+			JSON.stringify({
+				name: `${testName}-workspace-root`,
+				private: true
+			})
+		);
 	});
 
 	// runs before each test case
@@ -57,7 +72,13 @@ export function setupTest<Addons extends AddonMap>(addons: Addons) {
 			fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8');
 
 			// run addon
-			await installAddon({ cwd, addons, options, packageManager: 'pnpm' });
+			const { pnpmBuildDependencies } = await installAddon({
+				cwd,
+				addons,
+				options,
+				packageManager: 'pnpm'
+			});
+			addPnpmBuildDependendencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
 
 			return cwd;
 		};
diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts
index 9af9de8..5c6e5a1 100644
--- a/packages/addons/_tests/_setup/suite.ts
+++ b/packages/addons/_tests/_setup/suite.ts
@@ -3,7 +3,13 @@ import path from 'node:path';
 import { execSync } from 'node:child_process';
 import * as vitest from 'vitest';
 import { installAddon, type AddonMap, type OptionMap } from 'sv';
-import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/testing';
+import {
+	createProject,
+	startPreview,
+	addPnpmBuildDependendencies,
+	type CreateProject,
+	type ProjectVariant
+} from 'sv/testing';
 import { chromium, type Browser, type Page } from '@playwright/test';
 
 const cwd = vitest.inject('testDir');
@@ -40,6 +46,15 @@ export function setupTest<Addons extends AddonMap>(addons: Addons) {
 			"packages:\n  - '**/*'",
 			'utf8'
 		);
+
+		// creates a barebones package.json in each addon dir
+		fs.writeFileSync(
+			path.resolve(cwd, testName, 'package.json'),
+			JSON.stringify({
+				name: `${testName}-workspace-root`,
+				private: true
+			})
+		);
 	});
 
 	// runs before each test case
@@ -54,7 +69,13 @@ export function setupTest<Addons extends AddonMap>(addons: Addons) {
 			fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8');
 
 			// run addon
-			await installAddon({ cwd, addons, options, packageManager: 'pnpm' });
+			const { pnpmBuildDependencies } = await installAddon({
+				cwd,
+				addons,
+				options,
+				packageManager: 'pnpm'
+			});
+			addPnpmBuildDependendencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
 
 			return cwd;
 		};
diff --git a/packages/addons/_tests/tailwindcss/test.ts b/packages/addons/_tests/tailwindcss/test.ts
index 1ede105..cd692cf 100644
--- a/packages/addons/_tests/tailwindcss/test.ts
+++ b/packages/addons/_tests/tailwindcss/test.ts
@@ -16,25 +16,28 @@ test.concurrent.for(variants)('none - %s', async (variant, { page, ...ctx }) =>
 	ctx.onTestFinished(async () => await close());
 
 	const el = page.getByTestId('base');
-	await expect(el).toHaveCSS('background-color', 'rgb(71, 85, 105)');
-	await expect(el).toHaveCSS('border-color', 'rgb(249, 250, 251)');
+	await expect(el).toHaveCSS('background-color', 'oklch(0.446 0.043 257.281)');
+	await expect(el).toHaveCSS('border-color', 'oklch(0.985 0.002 247.839)');
 	await expect(el).toHaveCSS('border-width', '4px');
 	await expect(el).toHaveCSS('margin-top', '4px');
 });
 
-test.concurrent.for(variants)('typography - %s', async (variant, { page, ...ctx }) => {
-	const cwd = await ctx.run(variant, { tailwindcss: { plugins: ['typography'] } });
-
-	// ...add files
-	addFixture(cwd, variant);
-
-	const { close } = await prepareServer({ cwd, page });
-	// kill server process when we're done
-	ctx.onTestFinished(async () => await close());
-
-	const el = page.getByTestId('typography');
-	await expect(el).toHaveCSS('font-size', '18px');
-	await expect(el).toHaveCSS('line-height', '28px');
-	await expect(el).toHaveCSS('text-align', 'right');
-	await expect(el).toHaveCSS('text-decoration-line', 'line-through');
-});
+test.concurrent.for(variants)(
+	'typography without plugin - %s',
+	async (variant, { page, ...ctx }) => {
+		const cwd = await ctx.run(variant, { tailwindcss });
+
+		// ...add files
+		addFixture(cwd, variant);
+
+		const { close } = await prepareServer({ cwd, page });
+		// kill server process when we're done
+		ctx.onTestFinished(async () => await close());
+
+		const el = page.getByTestId('typography');
+		await expect(el).toHaveCSS('font-size', '18px');
+		await expect(el).toHaveCSS('line-height', '28px');
+		await expect(el).toHaveCSS('text-align', 'right');
+		await expect(el).toHaveCSS('text-decoration-line', 'line-through');
+	}
+);
diff --git a/packages/cli/lib/testing.ts b/packages/cli/lib/testing.ts
index 6285752..101214b 100644
--- a/packages/cli/lib/testing.ts
+++ b/packages/cli/lib/testing.ts
@@ -6,6 +6,7 @@ import { exec } from 'tinyexec';
 import { create } from '@sveltejs/create';
 import pstree, { type PS } from 'ps-tree';
 
+export { addPnpmBuildDependendencies } from '../utils/package-manager.ts';
 export type ProjectVariant = 'kit-js' | 'kit-ts' | 'vite-js' | 'vite-ts';
 
 const TEMPLATES_DIR = '.templates';
diff --git a/packages/create/shared/+library-typescript/jsconfig.json b/packages/create/shared/+library-typescript-checkjs/jsconfig.json
similarity index 100%
rename from packages/create/shared/+library-typescript/jsconfig.json
rename to packages/create/shared/+library-typescript-checkjs/jsconfig.json
diff --git a/packages/create/test/check.ts b/packages/create/test/check.ts
index ba807aa..f2e459c 100644
--- a/packages/create/test/check.ts
+++ b/packages/create/test/check.ts
@@ -37,7 +37,7 @@ const templates = fs.readdirSync(resolve_path('../templates/')) as TemplateType[
 for (const template of templates) {
 	if (template[0] === '.') continue;
 
-	for (const types of ['checkjs', 'typescript'] as LanguageType[]) {
+	for (const types of ['checkjs', 'typescript', 'none'] as LanguageType[]) {
 		const cwd = path.join(test_workspace_dir, `${template}-${types}`);
 		fs.rmSync(cwd, { recursive: true, force: true });