Skip to content

refactor(build): migrate tsup → tsdown#2513

Merged
joshuaellis merged 2 commits into
nextfrom
refactor/tsdown-migration
May 22, 2026
Merged

refactor(build): migrate tsup → tsdown#2513
joshuaellis merged 2 commits into
nextfrom
refactor/tsdown-migration

Conversation

@joshuaellis
Copy link
Copy Markdown
Member

@joshuaellis joshuaellis commented May 22, 2026

Why

tsup 8.5.1's DTS plugin unconditionally injects baseUrl: "." into the compiler options it hands to rollup-plugin-dts. TypeScript 6.0 rejects that with TS5101 ("Option 'baseUrl' is deprecated"), which is what blocked #2491. The existing ignoreDeprecations patch in tests.yml only covers the test-types matrix entry — the build job has none. Stacking more workarounds on a deprecated bundler is the wrong direction.

tsdown is rolldown-based, uses rolldown-plugin-dts (no baseUrl injection — verified against the plugin source), declares peer typescript: "^5.0.0 || ^6.0.0", and tsup's own README recommends the migration. Our Node floor already clears tsdown 0.22's ^22.18.0 || >=24.0.0 requirement, so no Node bump rides along.

Upstream tracking: egoist/tsup#1388.

Known behaviour difference

For each package's modern.mjs entry (the one carrying the canonical .d.mts), rolldown extracts its __exportAll runtime helper into a sibling dist/chunk.mjs. codeSplitting: false does not suppress this in tsdown 0.22 / rolldown 1.0. The chunk ships via each package's files: ["dist/**/*"] and is resolved as a relative import from the entry, so consumers are unaffected — arethetypeswrong is green across all four resolution modes (node10, node16 from CJS, node16 from ESM, bundler) for the produced tarballs.

.nvmrc was 22.15.0 → 24.16.0 and the CI surface moved to a Node
22.x/24.x unit-test matrix some time ago; CLAUDE.md still claimed
22.15.0 + Node 18/20, which is wrong on both counts.
tsup 8.5.1's DTS plugin unconditionally injects `baseUrl: "."` into the
compiler options it hands to rollup-plugin-dts. TypeScript 6.0 rejects
that with TS5101, blocking the root TS bump (see #2491). The workaround
in tests.yml only patched the test-types matrix and not the build job —
piling more workarounds on a deprecated bundler is the wrong direction.

tsdown is rolldown-based, uses rolldown-plugin-dts (no baseUrl
injection), declares peer typescript ^5 || ^6, and tsup's own README
recommends it.

What changes:

- tsup.config.base.ts → tsdown.config.base.mjs (+ matching .d.mts). JS +
  JSDoc rather than TS so the per-package tsdown.config.ts files load it
  through the native ESM loader; pnpm's strict isolation collides with
  tsdown's tsx loader.
- All 12 per-package tsup.config.ts → tsdown.config.ts.
- Each package's build/dev scripts swap tsup → tsdown and pre-clean
  dist/ (tsdown's clean defaults differ).
- Drop the now-dead test-types '6.0' jq patch + comment block.

The six-bundle layout (cjs dev + prod-min and esm legacy + modern +
modern.dev + modern.prod-min) is preserved byte-for-byte at the file
listing level — packages' public `exports` fields are unchanged.

Known behaviour difference: for the modern.mjs entry (the one carrying
.d.mts), rolldown extracts its `__exportAll` runtime helper into a
sibling dist/chunk.mjs that codeSplitting:false does not suppress in
tsdown 0.22 / rolldown 1.0. The chunk ships via each package's
`files: ["dist/**/*"]` and is resolved as a relative import from the
entry, so consumers are unaffected; are-the-types-wrong is green across
all resolution modes for the produced tarballs.

Refs: egoist/tsup#1388.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-spring Error Error May 22, 2026 12:02pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 22, 2026

⚠️ No Changeset found

Latest commit: b7cfe7e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Base automatically changed from docs/refresh-node-version-notes to next May 22, 2026 12:03
@joshuaellis joshuaellis merged commit d886f1b into next May 22, 2026
17 of 18 checks passed
@joshuaellis joshuaellis deleted the refactor/tsdown-migration branch May 22, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant