Skip to content

Improve PluginOptions types, JSDoc examples, and exports for Vite & PostCSS - #20522

Open
abdelrhmanahmed255 wants to merge 5 commits into
tailwindlabs:mainfrom
abdelrhmanahmed255:types/bundler-plugins-enhancement
Open

abdelrhmanahmed255 wants to merge 5 commits into
tailwindlabs:mainfrom
abdelrhmanahmed255:types/bundler-plugins-enhancement

Conversation

@abdelrhmanahmed255

Copy link
Copy Markdown

This PR improves the developer experience when configuring @tailwindcss/vite and @tailwindcss/postcss in TypeScript:

  • Added @default tags and @example code blocks to PluginOptions so IDEs (VS Code) display helpful tooltips and code completions when configuring the plugin.
  • Added explicit named exports for tailwindcss alongside the default exports in both packages to support both import tailwindcss and import { tailwindcss }.
  • Added a TypeScript usage section to the @tailwindcss/vite README.

@abdelrhmanahmed255
abdelrhmanahmed255 requested a review from a team as a code owner September 26, 2026 23:44
@greptile-apps

greptile-apps Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

[Low risk] Adds TypeScript documentation and named exports to plugin packages.

The PR should not merge until the PostCSS named export works through the CommonJS entry.

Reviews (1) · Last reviewed commit: "docs(vite): add TypeScript configuration..."

}

export default Object.assign(tailwindcss, { postcss: true }) as PluginCreator<PluginOptions>
export { tailwindcss }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Named export missing in CommonJS

In a CommonJS TypeScript project, import { tailwindcss } from '@tailwindcss/postcss' uses the package’s separate require entry. That entry exports only the function, not a tailwindcss property, so the new named import fails type-checking or resolves to undefined when required. The CommonJS entry needs to expose it too.

Knowledge Base Used: PostCSS plugin

}

export default Object.assign(tailwindcss, { postcss: true }) as PluginCreator<PluginOptions>
export { tailwindcss }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Named export loses creator type

The named and default exports refer to the same function at runtime, but only the default is typed as PluginCreator<PluginOptions>. The named export keeps the narrower function type, without the postcss: true marker, so TypeScript users cannot use it interchangeably with the default when registering a PostCSS plugin creator directly. Give both exports the same type.

Knowledge Base Used: PostCSS plugin

@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Walkthrough

The pull request expands PluginOptions documentation for the Vite and PostCSS packages. It adds defaults and configuration examples, and adds a Vite README example. Both packages also add a named tailwindcss export while retaining the default export.

Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to 823d9

Development-mode Vite builds may optimize CSS despite the new documentation, and CommonJS PostCSS users cannot access the added named export. These are bounded inconsistencies with localized corrections.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 823d9

The named imports expose the existing plugin factories, with no identified change to their privileges or execution paths. The available security coverage does not establish safety beyond the reviewed changes.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The additional import forms do not independently expand the reviewed plugins' filesystem, CSS compilation, or build authority beyond that available through their default exports.

Trust Boundaries and Controls

  • inferred — No separate trust or identity transition was identified for named-import callers: both names resolve to their respective existing plugin factories.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: improved PluginOptions documentation and added exports for Vite and PostCSS.
Description check ✅ Passed The description accurately explains the JSDoc improvements, named exports, and Vite README update.
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.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: ae2cb973-89c8-4cf2-8aac-b6d444c53f0d

📥 Commits

Reviewing files that changed from the base of the PR and between fa81d69 and 823d995.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/@tailwindcss-postcss/src/index.ts
  • packages/@tailwindcss-vite/README.md
  • packages/@tailwindcss-vite/src/index.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

Comment on lines 412 to +413
export default Object.assign(tailwindcss, { postcss: true }) as PluginCreator<PluginOptions>
export { tailwindcss }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

cat packages/@tailwindcss-postcss/src/index.cts
cat packages/@tailwindcss-postcss/package.json
rg -n 'require\\(|from .@tailwindcss/postcss.|tailwindcss.*export|named export|export =|export \\{ tailwindcss' packages/@tailwindcss-postcss packages --glob '*.{ts,tsx,cts,mts,js,md,json}'

Repository: tailwindlabs/tailwindcss

Length of output: 1943


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- PostCSS package files ---'
git ls-files packages/@tailwindcss-postcss
printf '%s\n' '--- PostCSS references and export expectations ---'
rg -n -F -e '@tailwindcss/postcss' -e 'tailwindcss' -e 'export =' -e 'export { tailwindcss }' packages/@tailwindcss-postcss packages --glob '*.{ts,tsx,cts,mts,js,md,json}' | head -240
printf '%s\n' '--- package entry patterns ---'
rg -n -F -e '"require"' -e '"import"' -e 'export =' packages --glob 'package.json' --glob '*.cts' --glob '*.ts' | head -240

Repository: tailwindlabs/tailwindcss

Length of output: 34233


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- PostCSS README API examples ---'
sed -n '40,115p' packages/@tailwindcss-postcss/README.md
printf '%s\n' '--- PostCSS test imports and entry usage ---'
sed -n '1,30p' packages/@tailwindcss-postcss/src/index.test.ts
printf '%s\n' '--- PostCSS source export area ---'
sed -n '100,116p' packages/@tailwindcss-postcss/src/index.ts
sed -n '406,416p' packages/@tailwindcss-postcss/src/index.ts
printf '%s\n' '--- analogous core package exports ---'
sed -n '1,35p' packages/tailwindcss/src/index.ts
sed -n '1,22p' packages/tailwindcss/src/index.cts
sed -n '15,60p' packages/tailwindcss/package.json
printf '%s\n' '--- analogous plugin exports ---'
cat packages/tailwindcss/src/plugin.ts
cat packages/tailwindcss/src/plugin.cts

Repository: tailwindlabs/tailwindcss

Length of output: 8376


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- exact PR diff ---'
git diff --unified=8 fa81d697fe572a10ac150d18964a093a7a874081 823d99541b313d90ad59ae0f5a13a010753885fc -- packages/@tailwindcss-postcss/src/index.ts packages/@tailwindcss-postcss/src/index.cts packages/@tailwindcss-postcss/package.json
printf '%s\n' '--- core ESM exports and CJS bridge ---'
rg -n -F -e 'export default' -e 'export {' -e 'for (let key in tailwindcss)' -e 'postcssPlugin[key]' packages/tailwindcss/src/index.ts packages/tailwindcss/src/index.cts
sed -n '1,28p' packages/tailwindcss/src/index.cts

Repository: tailwindlabs/tailwindcss

Length of output: 2810


Preserve the named export in the CommonJS entry.

src/index.ts now exports tailwindcss, but src/index.cts imports only the default and exposes it with export =. Therefore, require('@tailwindcss/postcss').tailwindcss is unavailable at runtime and in the CommonJS declaration. Copy the named exports as the core package does.

Suggested fix
-import tailwindcss from './index.ts'
+import postcssPlugin, * as tailwindcss from './index.ts'

 // This is used instead of `export default` to work around a bug in
 // `postcss-load-config`

+for (let key in tailwindcss) {
+  if (key === 'default') continue
+  // @ts-ignore
+  postcssPlugin[key] = tailwindcss[key]
+}
+
 // @ts-ignore
-export = tailwindcss
+export = postcssPlugin

Comment on lines +25 to +40
*
* @default true in production build, false in development
*
* @example
* ```ts
* import tailwindcss from '@tailwindcss/vite'
* import { defineConfig } from 'vite'
*
* export default defineConfig({
* plugins: [
* tailwindcss({
* optimize: { minify: true },
* }),
* ],
* })
* ```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

rg -n 'shouldOptimize|optimize\\(|generateBundle|transform\\(|apply:|command|NODE_ENV|cssMinify' packages/@tailwindcss-vite/src/index.ts
sed -n '70,115p' packages/@tailwindcss-vite/src/index.ts
sed -n '175,225p' packages/@tailwindcss-vite/src/index.ts
sed -n '260,315p' packages/@tailwindcss-vite/src/index.ts

Repository: tailwindlabs/tailwindcss

Length of output: 4959


Clarify the development default

The apply: 'serve' hook does not call optimize, but the apply: 'build' hook does. Since shouldOptimize remains true unless opts.optimize is set, a development-mode Vite build still optimizes CSS. The documentation should distinguish the development server from a development-mode build. The minify option controls minification separately.

Suggested fix
- * @default true in production build, false in development
+ * @default true during Vite builds, and false in the Vite development server
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
*
* @default true in production build, false in development
*
* @example
* ```ts
* import tailwindcss from '@tailwindcss/vite'
* import { defineConfig } from 'vite'
*
* export default defineConfig({
* plugins: [
* tailwindcss({
* optimize: { minify: true },
* }),
* ],
* })
* ```
*
* @default true during Vite builds, and false in the Vite development server
*
* @example
* ```ts
* import tailwindcss from '@tailwindcss/vite'
* import { defineConfig } from 'vite'
*
* export default defineConfig({
* plugins: [
* tailwindcss({
* optimize: { minify: true },
* }),
* ],
* })
* ```

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