Skip to content

chore(build): switch dts generation to rolldown-plugin-dts - #58

Merged
kibertoad merged 3 commits into
mainfrom
chore/rolldown-dts
Jul 6, 2026
Merged

chore(build): switch dts generation to rolldown-plugin-dts#58
kibertoad merged 3 commits into
mainfrom
chore/rolldown-dts

Conversation

@kibertoad

@kibertoad kibertoad commented Jul 6, 2026

Copy link
Copy Markdown
Owner

What

Replaces vite-plugin-dts with rolldown-plugin-dts across all 15 library packages, and bumps vite to ^8.1.3 and vitest to ^4.1.10 workspace-wide.

Why

rolldown-plugin-dts is the rolldown-native declaration bundler (the one tsdown uses, and the one Vite itself moved to internally). Vite 8 is already rolldown-powered here, so this is the natural fit:

  • Drops the @microsoft/api-extractor dependency chain that vite-plugin-dts pulls in for rollupTypes.
  • Bundles types with the repo's own TypeScript 6.0.3 instead of api-extractor's bundled 5.9.3, so the *** The target project appears to use TypeScript 6.0.3 which is newer than the bundled compiler engine warning is gone.
  • Declaration output now code-splits shared types into a chunk, mirroring the existing JS code-splitting.

Config changes per package

  • import { dts } from "rolldown-plugin-dts" (named export instead of default).
  • Gate the plugin to the build command so it does not run under vitest. vite-plugin-dts guarded this internally; this plugin does not, and its buildStart hook throws in serve/test mode (TypeError: Cannot convert undefined or null to object).
  • Use object-form lib.entry so the emitted chunk keeps its .d.ts extension. A string entry + fileName clobbers it to .ts.
  • Add the oxc.exclude guard recommended for Vite so generated declaration files are not re-transformed.

Compatibility

The published type surface is unchanged. The only difference versus the previous output is that api-extractor's collision rename TransitionEvent_2 is gone; the author's intended export name TransitionEvent is kept (it was already re-exported under that name).

Considered alternative

unplugin-dts is the cross-bundler successor to vite-plugin-dts and supports rolldown, but its bundleTypes still relies on @microsoft/api-extractor. rolldown-plugin-dts was chosen because it is genuinely rolldown-native and removes api-extractor entirely.

Verification

  • pnpm build: 34/34 tasks pass; every package emits a proper index.d.ts (and testing.d.ts for multi-entry packages).
  • pnpm typecheck: clean across the whole workspace, including all example apps that consume the generated .d.ts.
  • pnpm test: all pass except @tanstack-react-modules/cli#test, which is the pre-existing Windows .test-output EPERM flake (unrelated; that package does not use the dts plugin).

Note

pnpm auto-added a minimumReleaseAgeExclude block in pnpm-workspace.yaml for vitest@4.1.10 because it is newer than the workspace release-age gate. This is required for the vitest bump to install.

Summary by CodeRabbit

  • Chores
    • Updated the project’s build and test tooling across multiple packages for newer, more stable versions.
    • Swapped out the type-generation setup and refined build settings to better handle library outputs and generated files.

Replace vite-plugin-dts with rolldown-plugin-dts across all 15 library
packages. rolldown-plugin-dts is the rolldown-native declaration bundler
(used by tsdown) and drops the @microsoft/api-extractor dependency chain.
It bundles types with the project's own TypeScript 6.0.3 instead of
api-extractor's bundled 5.9.3, so the version-mismatch warning is gone.

Config changes per package:
- import { dts } from "rolldown-plugin-dts" (default export -> named)
- gate the plugin to the build command so it does not run under vitest
  (vite-plugin-dts guarded this internally; this plugin does not, and its
  buildStart hook throws in serve/test mode)
- use object-form lib.entry so the emitted chunk keeps its .d.ts extension
  (a string entry + fileName clobbers it to .ts)
- add the oxc.exclude guard recommended for Vite so generated declaration
  files are not re-transformed

The published type surface is unchanged. The only diff versus the previous
output is that api-extractor's collision rename TransitionEvent_2 is gone;
the author's intended export name TransitionEvent is kept. Declaration
output now code-splits shared types into a chunk, mirroring the existing
JS code-splitting.

Also bump vite to ^8.1.3 and vitest to ^4.1.10 workspace-wide. pnpm added
a minimumReleaseAgeExclude entry for vitest@4.1.10 since it is newer than
the workspace release-age gate.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kibertoad, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 49 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 81e3d25f-ba8c-4aa8-adad-ae0ee0fb5d23

📥 Commits

Reviewing files that changed from the base of the PR and between 5ac8f01 and cae118d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • examples/react-router/active-project-manifest/shell/package.json
  • examples/react-router/customer-onboarding-journey/shell/package.json
  • examples/react-router/editor-composition/shell/package.json
  • examples/react-router/integration-manager/shell/package.json
  • examples/react-router/integration-setup-journey/shell/package.json
  • examples/react-router/journey-invoke/shell/package.json
  • examples/react-router/remote-capabilities/shell/package.json
  • examples/tanstack-router/customer-onboarding-journey/shell/package.json
  • examples/tanstack-router/editor-composition/shell/package.json
  • examples/tanstack-router/integration-manager/shell/package.json
  • examples/tanstack-router/integration-setup-journey/shell/package.json
  • examples/tanstack-router/journey-invoke/shell/package.json
  • examples/tanstack-router/remote-capabilities/shell/package.json
  • pnpm-workspace.yaml
📝 Walkthrough

Walkthrough

This PR uniformly bumps vite and vitest versions across all workspace packages and replaces vite-plugin-dts with rolldown-plugin-dts in devDependencies and vite.config.ts files. Configs switch to a command-based defineConfig callback, enable the DTS plugin only for build, update build.lib.entry shape, and add oxc.exclude rules. pnpm-workspace.yaml adds a rolldown override and release-age exclusions.

Changes

Tooling migration across packages

Layer / File(s) Summary
Vite/vitest bump only
packages/catalog/package.json, packages/react-router-cli/package.json, packages/tanstack-router-cli/package.json
Bumps vite and/or vitest versions without DTS plugin changes.
compositions / compositions-engine migration
packages/compositions*/package.json, packages/compositions*/vite.config.ts
Replaces vite-plugin-dts with rolldown-plugin-dts, adopts command-based config with build-only DTS plugin, and adds oxc.exclude.
core / frontend-core migration
packages/core/*, packages/frontend-core/*
Updates devDependencies and vite.config.ts to use rolldown-plugin-dts, object-form build.lib.entry, and oxc.exclude.
journeys / journeys-engine migration
packages/journeys*/package.json, packages/journeys*/vite.config.ts
Switches to rolldown-plugin-dts with build-only plugin activation and oxc.exclude additions.
react-router-core/runtime/testing migration
packages/react-router-{core,runtime,testing}/*
Updates devDependencies and vite.config.ts to rolldown-plugin-dts, object-form entry, removed fileName, and oxc.exclude.
react / vue migration
packages/react/*, packages/vue/*
Applies the same DTS plugin swap, entry shape change, and oxc.exclude pattern.
tanstack-router-core/runtime/testing migration
packages/tanstack-router-{core,runtime,testing}/*
Applies the same DTS plugin swap, entry shape change, and oxc.exclude pattern.
testing package and workspace config
packages/testing/*, pnpm-workspace.yaml
Updates testing package tooling and adds rollupOptions.external/sourcemap; workspace config pins rolldown version via override and excludes specific vitest versions from minimum release-age enforcement.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Suggested labels: skip-release

Suggested reviewers: diogomiguel

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: replacing vite-plugin-dts with rolldown-plugin-dts for build-time type generation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/rolldown-dts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

pnpm peer resolution was resolving rolldown-plugin-dts against two
different rolldown backends: most packages got rolldown@1.1.4 (from
vite 8.1.x), but frontend-core and journeys-engine got the pre-release
rolldown@1.0.0-rc.18 that is still in the tree via the examples' vite
8.0.x. That meant dts for those two packages was generated through a
different, pre-release backend than the rest of the workspace.

Add a scoped `rolldown-plugin-dts>rolldown: 1.1.4` override so every
package generates declarations through the same rolldown, without
touching the examples' own vite. Full build (34/34) and typecheck
(113/113) pass.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/frontend-core/vite.config.ts (1)

2-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting the shared dts/oxc boilerplate into a workspace helper.

The plugins: command === "build" ? [dts()] : [] activation and oxc: { exclude: [/\.js$/, /\.d\.[cm]?ts$/] } block are duplicated verbatim across every migrated vite.config.ts (frontend-core, tanstack-router-core, tanstack-router-runtime, tanstack-router-testing, and reportedly 11 more packages per the PR objectives). Extracting a small shared factory (e.g. createLibConfig() in a workspace-internal package) would let all 15 configs stay in sync automatically for future tweaks (e.g. adding dts() options).

♻️ Example shared helper
// tools/vite-lib-preset.ts
import { dts } from "rolldown-plugin-dts";
import type { ConfigEnv, UserConfig } from "vite";

export function libDtsPlugins({ command }: ConfigEnv) {
  return command === "build" ? [dts()] : [];
}

export const oxcDtsExclude = {
  exclude: [/\.js$/, /\.d\.[cm]?ts$/],
} satisfies UserConfig["oxc"];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/frontend-core/vite.config.ts` around lines 2 - 16, The Vite config
still contains duplicated dts/oxc boilerplate, so extract the shared lib preset
into a workspace helper and reuse it here. Move the build-only dts plugin
activation from the existing defineConfig callback and the repeated oxc.exclude
pattern into a shared factory such as createLibConfig() or equivalent, then have
this config consume that helper so future changes stay consistent across all
migrated packages.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/frontend-core/vite.config.ts`:
- Around line 2-16: The Vite config still contains duplicated dts/oxc
boilerplate, so extract the shared lib preset into a workspace helper and reuse
it here. Move the build-only dts plugin activation from the existing
defineConfig callback and the repeated oxc.exclude pattern into a shared factory
such as createLibConfig() or equivalent, then have this config consume that
helper so future changes stay consistent across all migrated packages.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 136f4cc6-e9c0-4aa6-9d15-335403a50cf6

📥 Commits

Reviewing files that changed from the base of the PR and between 1bd0b0c and 5ac8f01.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (34)
  • packages/catalog/package.json
  • packages/compositions-engine/package.json
  • packages/compositions-engine/vite.config.ts
  • packages/compositions/package.json
  • packages/compositions/vite.config.ts
  • packages/core/package.json
  • packages/core/vite.config.ts
  • packages/frontend-core/package.json
  • packages/frontend-core/vite.config.ts
  • packages/journeys-engine/package.json
  • packages/journeys-engine/vite.config.ts
  • packages/journeys/package.json
  • packages/journeys/vite.config.ts
  • packages/react-router-cli/package.json
  • packages/react-router-core/package.json
  • packages/react-router-core/vite.config.ts
  • packages/react-router-runtime/package.json
  • packages/react-router-runtime/vite.config.ts
  • packages/react-router-testing/package.json
  • packages/react-router-testing/vite.config.ts
  • packages/react/package.json
  • packages/react/vite.config.ts
  • packages/tanstack-router-cli/package.json
  • packages/tanstack-router-core/package.json
  • packages/tanstack-router-core/vite.config.ts
  • packages/tanstack-router-runtime/package.json
  • packages/tanstack-router-runtime/vite.config.ts
  • packages/tanstack-router-testing/package.json
  • packages/tanstack-router-testing/vite.config.ts
  • packages/testing/package.json
  • packages/testing/vite.config.ts
  • packages/vue/package.json
  • packages/vue/vite.config.ts
  • pnpm-workspace.yaml

Move all 13 example shells to vite ^8.1.3 (nine were on ^8.0.3, four on
^6.0.0), and bump the four vite-6 shells' @vitejs/plugin-react to ^6.0.1
to match the rest. This removes vite 8.0.11 and vite 6 from the tree,
which also removes the pre-release rolldown@1.0.0-rc.18 that the earlier
dts-backend split resolved through.

The rolldown-plugin-dts>rolldown override now has nothing older to
resolve against, so it stays purely as a guard against a future example
reintroducing an older vite. Comment reworded to reflect that.

All four vite 6->8 shells build under vite 8.1.3. Full build (34/34) and
typecheck (113/113) pass.
@kibertoad
kibertoad merged commit 4d1fc3c into main Jul 6, 2026
40 of 41 checks passed
@kibertoad
kibertoad deleted the chore/rolldown-dts branch July 6, 2026 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant