Skip to content

Do not retain the finished build's plugin context in @tailwindcss/vite - #20503

Open
lazerg wants to merge 3 commits into
tailwindlabs:mainfrom
lazerg:fix/issue-20501-vite-plugin-context-leak
Open

lazerg wants to merge 3 commits into
tailwindlabs:mainfrom
lazerg:fix/issue-20501-vite-plugin-context-leak

Conversation

@lazerg

@lazerg lazerg commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary

The build plugin's Root caches a compiler for as long as the plugin instance lives, but that compiler holds onto the PluginContext from the transform call that first created it, through the onDependency callback passed to compile(). Nothing ever released that captured context. In a plain vite build this never shows up because the process exits right after, but if the same plugin instance is reused afterward (Astro's static build runs the SSR/prerender build and then generates every page in the same process) the finished build's context, and the native Rolldown arena behind it, stay alive while the next phase starts allocating on top of it.

This clears the cached roots for an environment as soon as its bundle closes, so the reference is dropped before anything else gets a chance to run.

Fixes #20501

Test plan

Added a test that wraps the build plugin's transform handler to grab a WeakRef on the PluginContext from the first call, runs a Vite 8 (Rolldown) build, forces a few GCs, and checks the context was collected. It fails on the old code and passes with the fix (only reproduces under Rolldown, not Rollup). Ran the full integrations/vite suite locally and it passes.

@lazerg
lazerg requested a review from a team as a code owner September 21, 2026 03:42
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 0d12ec33-86b4-44af-b0e2-ce255699b9e6

📥 Commits

Reviewing files that changed from the base of the PR and between d9541bd and ff8a6f6.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 23ba9d88-8ccc-4aee-ad5e-ddac616da700

📥 Commits

Reviewing files that changed from the base of the PR and between 44eca1b and d9541bd.

📒 Files selected for processing (2)
  • integrations/vite/plugin-context-leak.test.ts
  • packages/@tailwindcss-vite/src/index.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


Walkthrough

The Vite build plugin now preserves cached roots during watch rebuilds. For non-watch builds, closeBundle clears cached roots so finished-build PluginContext instances can be collected. A Vite 8 integration test verifies this with WeakRef and forced garbage collection. The changelog records the fix for memory retention in long-lived build processes.

Priority: ⬆️ High

Severity of issue fixed: High

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: releasing the finished build's plugin context in @tailwindcss/vite.
Description check ✅ Passed The description explains the retained PluginContext issue, the root-cache fix, watch-mode behavior, and the garbage-collection test.
Linked Issues check ✅ Passed Issue #20501 requires release of cached build roots after a completed bundle, retention of roots during watch rebuilds, and a test for context collection. packages/@tailwindcss-vite/src/index.ts cle…
Out of Scope Changes check ✅ Passed The source change, regression test, and CHANGELOG.md entry directly support Issue #20501. The changes add no unrelated product behavior or public API changes.

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.

@greptile-apps

greptile-apps Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge, with cleanup correctly limited to completed non-watch builds and regression coverage for the retained context.

Reviews (3) · Last reviewed commit: "Don't clear the build plugin's Root cach..."

@lazerg
lazerg force-pushed the fix/issue-20501-vite-plugin-context-leak branch from d9541bd to ff8a6f6 Compare September 21, 2026 04:04
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.

@tailwindcss/vite: cached Root.compiler pins the build's plugin context, keeping the finished bundle alive (multi-GB RSS in Astro SSG)

1 participant