Data note
25

Data note · Published Nov 15, 2025

Tailwind v4 Missed Every Class in My Shared Package

Tailwind v4 rendered my shared components without their utility classes. One @source directive fixed three hours of monorepo debugging.

A field-guide drawing of a monarch butterfly on milkweed
In this article3 sections

After I upgraded a pnpm monorepo to Tailwind v4, every component in packages/shared-components lost its utility styles. The app compiled. The class names were present in the markup. Tailwind simply never generated their CSS.

What you see in the browser:

<button className="text-(--btn-icon) bg-(--btn-bg)" />

The classes do not exist, and the raw function syntax just sits there unstyled.

Why It Breaks

Tailwind v4 moved configuration from JS to CSS. The old tailwind.config.js with content: paths is ignored.

Warning The new automatic detection only scans inside your own package. It does not look at sibling packages in your workspace.

Fix: Add @source

In your app’s CSS file (packages/main-app/src/app.css):

@import 'tailwindcss';
@source '../shared-components/src/**/*.{js,ts,jsx,tsx}';

@theme {
  --btn-icon: #222;
  --btn-bg: #cfcfcf;
  --radius-lg: 0.5rem;
}

The @source directive tells Tailwind where to find classes in other packages.

Multiple packages? Add multiple directives:

@import 'tailwindcss';
@source '../shared-components/src/**/*.{js,ts,jsx,tsx}';
@source '../shared-utils/src/**/*.{js,ts,jsx,tsx}';
@source '../shared-hooks/src/**/*.{js,ts,jsx,tsx}';

@theme {
  --btn-icon: #222;
  --btn-bg: #cfcfcf;
}

Your component now works:

export function Button({ children }) {
  return (
    <button className="text-(--btn-icon) bg-(--btn-bg) rounded-(--radius-lg)">
      {children}
    </button>
  );
}

This took me three hours to find because there was no error. The build succeeded; the missing CSS was the only clue.

What Changed

TailwindConfigMonorepo Support
v3JS content: [] arrayWorks if you list all paths
v4CSS @source directiveWorks if you add @source

The path in @source is relative to your CSS file. Tailwind documents the directive in its functions and directives reference.

If I add another shared package later, I also have to add another @source directive. That small piece of explicit configuration is now part of creating a workspace package.

One quick signal

Did this earn your time?

What was missing?

Thanks. That gives me something concrete to check.