tsdown-migrate — скилл для Claude Code: перенос с tsup на tsdown
Скилл ведёт миграцию TypeScript-библиотеки с tsup на tsdown: таблицы соответствия опций, различия в значениях по умолчанию и замена убранных опций.
npx skills add rolldown/tsdown --skill tsdown-migrate -a claude-codeЧто делает tsdown-migrate
Скилл нужен, когда проект на tsup пора перевести на tsdown — сборщик библиотек на Rolldown. Внутри лежит база знаний: переименования опций, правила переноса конфига, различия в значениях по умолчанию и варианты замены для опций, которых в tsdown больше нет.
Главная тонкость в двух этапах. tsdown v0.23 убрал совместимые с tsup опции — bundle, outExtension, publicDir, removeNodeProtocol, injectStyle, skipNodeModulesBundle. На новых версиях они не проходят проверку типов и молча игнорируются при сборке, поэтому пропущенное переименование даёт неверный вывод без ошибки. Скилл советует сначала мигрировать на [email protected] — последнюю версию, которая эти опции ещё принимает и помечает предупреждением об устаревании. Сборка без предупреждений и есть проверка полноты миграции. Только после неё — переход на ^0.23.0 или новее.
Для работы нужен Node.js ^22.18.0 || ^24.11.0 || >=26.0.0 — это требование к среде сборки, не к результату. Библиотека, которая раньше поддерживала Node.js 18 или 20, может сохранить поддержку через опцию target: собирайте на Node.js 22+ в CI, а готовый вывод тестируйте на нужных старых версиях. В конфиге external и noExternal — единственные имена из tsup, которые tsdown v0.23 ещё принимает, и смешивать их с deps.neverBundle или deps.alwaysBundle нельзя, иначе сборка падает с ошибкой.
Какие задачи решает
- перенести конфиг с
tsup.config.*наtsdown.config.*без пропущенных опций - заменить убранные в tsdown v0.23 опции совместимости
- сохранить прежние значения по умолчанию для format, clean, dts и target
- разобраться, почему сборка на новой версии выдаёт неверный вывод без ошибок
- перевести
externalиnoExternalв пространствоdeps
Примеры запросов агенту
- мигрируй этот проект с tsup на tsdown по шагам из скилла
- проверь tsdown.config.ts и найди оставшиеся опции из tsup
- почему сборка на tsdown v0.23 игнорирует мои опции?
Как установить tsdown-migrate
1Через Skills CLI (Vercel)
npx skills add rolldown/tsdown --skill tsdown-migrate -a claude-code2Вручную: положить файлы
~/.claude/skills/tsdown-migrate/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/tsdown-migrate/
1Через Skills CLI (Vercel)
npx skills add rolldown/tsdown --skill tsdown-migrate -a codex2Вручную: положить файлы
.agents/skills/tsdown-migrate/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add rolldown/tsdown --skill tsdown-migrate -a cursor2Вручную: положить файлы
.cursor/skills/tsdown-migrate/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install rolldown/tsdown tsdown-migrate2Вручную: положить файлы
.github/skills/tsdown-migrate/SKILL.md1Через Skills CLI (Vercel)
npx skills add rolldown/tsdown --skill tsdown-migrate -a gemini-cli2Командой платформы
gemini skills install https://github.com/rolldown/tsdown --path skills/tsdown-migrateВручную: положить файлы
.devin/skills/tsdown-migrate/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add rolldown/tsdown --skill tsdown-migrate -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора2
Похожие
Рядом в теме «Языки программирования»
Все скиллы по теме «Языки программирования» →Вопросы о tsdown-migrate
Как установить tsdown-migrate в Claude?
Выполните npx skills add rolldown/tsdown --skill tsdown-migrate -a claude-code. Скилл появится в ~/.claude/skills/tsdown-migrate/SKILL.md.
Что делает tsdown-migrate?
Проводит миграцию TypeScript-библиотеки с tsup на tsdown: переименовывает опции, переносит конфиг, подсказывает замену для убранных опций и указывает, какие значения по умолчанию отличаются.
Почему миграцию советуют делать в два этапа?
На tsdown v0.23 убранные опции совместимости молча игнорируются при сборке, и ошибку не видно. На [email protected] каждая такая опция даёт предупреждение об устаревании, поэтому сборка без предупреждений подтверждает, что миграция завершена, и только потом можно обновляться до ^0.23.0.
Исходный текст
SKILL.md · MIT
--- name: tsdown-migrate description: Migrate TypeScript library projects from tsup to tsdown. Provides complete option mappings, config transformation rules, default value differences, and unsupported option alternatives so AI agents can intelligently perform migrations. --- # Migrating from tsup to tsdown Knowledge base for AI agents to migrate tsup projects to tsdown — the Rolldown-powered library bundler. ## Target Version: Two-Stage Migration tsdown v0.23 removed all previously-deprecated tsup compatibility options — `bundle`, `outExtension`, `publicDir`, `removeNodeProtocol`, `injectStyle`, and `skipNodeModulesBundle` are no longer recognized. They fail TypeScript type checking and are **silently ignored at runtime**, so a missed mapping on v0.23+ produces wrong output without any error. Migrating directly to v0.23+ is therefore unsafe. tsdown **v0.22.14** is the last version that still accepts these options and flags each one with a deprecation warning, making it the safe migration checkpoint. Migrate in **two stages**: 1. **Stage 1 — migrate on `[email protected]`**: Install `[email protected]`, migrate the config per the tables below, run a build, and resolve **every** deprecation warning by mapping each flagged tsup option to its real tsdown equivalent. The warnings are the completeness check — the migration is not done until the build produces **zero warnings**. 2. **Stage 2 — upgrade to the latest tsdown (`^0.23.0` or newer)**: Only after a warning-free build on 0.22.14. Since the config no longer uses any removed compat options, the silent-ignore behavior of v0.23+ is no longer a risk. ## Runtime Requirement `tsdown` requires **Node.js `^22.18.0 || ^24.11.0 || >=26.0.0` to run** (build-time only) — that is, Node.js 22.18+, 24.11+, or 26+. Odd-numbered and EOL release lines (e.g. Node.js 23, 25) are not supported. The bundled output can still target lower Node.js versions via the [`target`](../tsdown/references/option-target.md) option, so a library that previously supported Node.js 18 / 20 with tsup can continue to do so after migrating. Recommended workflow when supporting Node.js 18 / 20: - **Build with Node.js 22+ in CI**, setting an explicit `target` such as `'node18'` or `'node20'`. - **Test the built output (or the packed tarball) on the lower Node.js versions** you need to support. ## When to Use - Migrating a project from tsup to tsdown - Understanding differences between tsup and tsdown options - Reviewing or fixing post-migration configuration issues - Advising users on tsup→tsdown compatibility ## Migration Overview Follow these steps to migrate a tsup project: 1. **Rename config file**: `tsup.config.*` → `tsdown.config.*` 2. **Update imports**: `'tsup'` → `'tsdown'` 3. **Apply option mappings**: Rename/transform options per tables below 4. **Preserve tsup defaults**: Explicitly set options that differ (format, clean, dts, target) 5. **Update package.json**: Dependencies (Stage 1: `[email protected]`), scripts, root config field 6. **Remove unsupported options**: Replace with alternatives where available 7. **Test build on 0.22.14**: Run `tsdown` and resolve every deprecation warning — zero warnings required 8. **Upgrade to latest tsdown** (`^0.23.0` or newer) and verify the build again ## Config File Migration ### File Rename | tsup | tsdown | |------|--------| | `tsup.config.ts` | `tsdown.config.ts` | | `tsup.config.cts` | `tsdown.config.cts` | | `tsup.config.mts` | `tsdown.config.mts` | | `tsup.config.js` | `tsdown.config.js` | | `tsup.config.cjs` | `tsdown.config.cjs` | | `tsup.config.mjs` | `tsdown.config.mjs` | | `tsup.config.json` | `tsdown.config.json` | ### Import and Identifier Changes ```ts // Before import { defineConfig } from 'tsup' // After import { defineConfig } from 'tsdown' ``` Replace all identifiers: `tsup` → `tsdown`, `TSUP` → `TSDOWN`. ## Option Mappings ### Property Renames | tsup | tsdown | Notes | |------|--------|-------| | `entryPoints` | `entry` | Also deprecated in tsup itself | | `cjsInterop` | `cjsDefault` | CJS default export handling | | `esbuildPlugins` | `plugins` | Now uses Rolldown/Unplugin plugins | | `outExtension` | `outExtensions` | Custom output extensions | | `publicDir` | `copy` | Copy static files to output | | `bundle: true` | _(remove)_ | Bundle is default behavior | | `bundle: false` | `unbundle: true` | Preserve file structure | | `removeNodeProtocol: true` | `nodeProtocol: 'strip'` | Strip `node:` prefix | | `injectStyle: true` | `css: { inject: true }` | CSS injection | | `injectStyle: false` | _(remove)_ | Default behavior | | `skipNodeModulesBundle` | `deps: { neverBundle: true }` | Externalize all dependencies | None of the old names are recognized by tsdown v0.23+ — always emit the new names. The compatibility options (`outExtension`, `skipNodeModulesBundle`, `publicDir`, `bundle`, `removeNodeProtocol`, `injectStyle`) were accepted with deprecation warnings up to v0.22.14 and removed entirely in v0.23; on v0.23+ leftovers are silently ignored, not errors, so builds misbehave without warning. This is why Stage 1 runs on v0.22.14, where every leftover is flagged. ### Deprecated but Still Accepted `external` and `noExternal` are the **only** tsup option names tsdown v0.23 still accepts. They emit deprecation warnings, will be removed in a future version, and cannot be combined with their replacements (mixing `external` with `deps.neverBundle`, or `noExternal` with `deps.alwaysBundle`, throws an error). Always emit the replacements. | tsup (deprecated) | tsdown (preferred) | Notes | |--------------------|--------------------|-------| | `external: [...]` | `deps: { neverBundle: [...] }` | Moved to deps namespace | | `noExternal: [...]` | `deps: { alwaysBundle: [...] }` | Moved to deps namespace | ### Output Filename Differences For IIFE builds, `tsdown` emits names like `[name].iife.js`, while `tsup` commonly emitted `[name].global.js`. `outExtensions` customizes extensions or suffixes, but it does not remove the built-in `.iife` or `.umd` segment. Use `outputOptions.entryFileNames: '[name].global.js'` to preserve old IIFE filenames. ### Dependency Namespace Moves Dependencies config moved under `deps` namespace. If both `external` and `noExternal` exist, merge into a single `deps` object: ```ts // Before (tsup) export default defineConfig({ external: ['react'], noExternal: ['lodash-es'], }) // After (tsdown) export default defineConfig({ deps: { neverBundle: ['react'], alwaysBundle: ['lodash-es'], }, }) ``` tsdown also adds `deps.onlyBundle` (whitelist of allowed bundled packages) — no tsup equivalent. Dependency handling defaults in tsdown v0.23+: - `dependencies`, `peerDependencies`, and **`optionalDependencies`** are all externalized by default (tsup only externalizes `dependencies` and `peerDependencies`, so `optionalDependencies` may switch from bundled to external after migration). - `deps.resolveDepSubpath` (resolving subpath imports of externalized packages without an `exports` field) is **disabled by default**. ### Plugin Import Transforms ```ts // Before (tsup - esbuild plugins) import plugin from 'unplugin-example/esbuild' // After (tsdown - Rolldown plugins) import plugin from 'unplugin-example/rolldown' ``` All `unplugin-*/esbuild` imports should change to `unplugin-*/rolldown`. For complete before/after examples of every transformation, see [guide-option-mappings.md](references/guide-option-mappings.md). ## Default Value Differences tsdown changes several defaults from tsup. When migrating, explicitly set these to preserve tsup behavior, then let the user decide which new defaults to adopt. | Option | tsup Default | tsdown Default | Migration Action | |--------|-------------|----------------|-----------------| | `format` | `'cjs'` | `'esm'` | Set `format: 'cjs'` to preserve | | `clean` | `false` | `true` | Set `clean: false` to preserve | | `dts` | `false` | Auto-enabled if `types`/`typings` in package.json | Set `dts: false` to preserve | | `target` | _(none)_ | Auto-reads from `engines.node` in package.json | Set `target: false` to preserve | After migration, suggest the user review these — tsdown's defaults are generally better: - ESM is the modern standard - Cleaning output prevents stale files - Auto DTS from package.json reduces config - Auto target from engines.node ensures consistency ## Unsupported Options These tsup options have no direct equivalent in tsdown. Remove them and inform the user. | tsup Option | Status | Alternative | |-------------|--------|-------------| | `splitting` | Always enabled | Remove — code splitting cannot be disabled in tsdown | | `metafile` | Not available | Suggest `devtools: true` for Vite DevTools bundle analysis | | `swc` | Not supported | Remove — tsdown uses oxc for transformation (built-in) | | `experimentalDts` | Not supported | Use the `dts` option instead | | `legacyOutput` | Not supported | Remove — no alternative | | `plugins` (tsup experimental) | Incompatible | Migrate to Rolldown plugins manually; tsup's plugin API differs from Rolldown's | ## Package.json Migration ### Scripts Replace `tsup` and `tsup-node` with `tsdown` in all script commands: ```json // Before { "scripts": { "build": "tsup src/index.ts", "dev": "tsup --watch" } } // After { "scripts": { "build": "tsdown src/index.ts", "dev": "tsdown --watch" } } ``` ### Dependencies | Location | Action | |----------|--------| | `dependencies.tsup` | Rename to `dependencies.tsdown` | | `devDependencies.tsup` | Rename to `devDependencies.tsdown` | | `optionalDependencies.tsup` | Rename to `optionalDependencies.tsdown` | | `peerDependencies.tsup` | Rename to `peerDependencies.tsdown` | | `peerDependenciesMeta.tsup` | Rename to `peerDependenciesMeta.tsdown` | ### Root Config Field If package.json has a root-level `tsup` field (inline config), rename to `tsdown`: ```json // Before { "tsup": { "entry": ["src/index.ts"] } } // After { "tsdown": { "entry": ["src/index.ts"] } } ``` For detailed package.json examples, see [guide-package-json.md](references/guide-package-json.md). ## New tsdown Features After migration, suggest these tsdown-exclusive features to the user: | Feature | Config | Description | |---------|--------|-------------| | Node protocol | `nodeProtocol: true \| 'strip'` | Add or strip `node:` prefix on built-in imports | | Workspace | `workspace: 'packages/*'` | Build multiple packages in a monorepo | | Package exports | `exports: true` | Auto-generate `exports` field in package.json | | Package validation | `publint: true`, `attw: true` | Lint package and check type correctness | | Executable | `exe: true` | Bundle as Node.js standalone executable (SEA) | | DevTools | `devtools: true` | Vite DevTools integration for bundle analysis | | Hooks | `hooks: { 'build:done': ... }` | Lifecycle hooks: `build:prepare`, `build:before`, `build:done` | | CSS modules | `css: { modules: { ... } }` | Scoped class names for `.module.css` files | | Glob import | `globImport: true` | Support `import.meta.glob` (Vite-style) | For detailed comparisons, see [guide-differences-detailed.md](references/guide-differences-detailed.md). ## References | Topic | Description | Reference | |-------|-------------|-----------| | Option Mappings | Complete before/after for every option transform | [guide-option-mappings](references/guide-option-mappings.md) | | Detailed Differences | Architecture, features, compatibility comparison | [guide-differences-detailed](references/guide-differences-detailed.md) | | Package.json | Dependency, script, and config field migration | [guide-package-json](references/guide-package-json.md) | ## Migration Checklist Use this checklist when performing a migration: ``` - [ ] Rename tsup.config.* → tsdown.config.* - [ ] Update import from 'tsup' to 'tsdown' - [ ] Replace tsup/TSUP identifiers with tsdown/TSDOWN - [ ] Apply property renames (cjsInterop→cjsDefault, esbuildPlugins→plugins, outExtension→outExtensions, publicDir→copy, bundle→unbundle, removeNodeProtocol→nodeProtocol, injectStyle→css.inject) - [ ] Move external/noExternal into deps namespace, replace skipNodeModulesBundle with `deps.neverBundle: true` - [ ] Update unplugin imports from /esbuild to /rolldown - [ ] Set explicit defaults to preserve tsup behavior (format, clean, dts, target) - [ ] Remove unsupported options (splitting, metafile, swc, etc.) - [ ] Update package.json scripts (tsup→tsdown) - [ ] Update package.json dependencies (Stage 1: [email protected]) - [ ] Rename root-level tsup config field if present - [ ] Run tsdown on 0.22.14 and resolve every deprecation warning (zero warnings required) - [ ] Upgrade to the latest tsdown (^0.23.0 or newer) and verify the build again - [ ] Suggest new tsdown features to the user ```
© rolldown · MIT · rolldown/tsdown