How to handle @source for a React UI Library in production?

3 weeks ago 23
ARTICLE AD BOX

@source is important for TailwindCSS; however, it has no effect in production because it is not part of the compiled CSS output. It is a CSS-first configuration directive.

When building packages with TailwindCSS, it is not recommended to ship compiled CSS. Doing so negates one of Tailwind’s key advantages: shipping only the styles that are actually used.

TailwindCSS-based packages should provide proper installation instructions so that developers consuming the package can correctly integrate it into their final project. In practice, this means clearly instructing consumers to include an @source directive that points to your package within their project.

final project CSS entrypoint

@import "tailwindcss"; @source "./path/to/project-root/node_modules/your-library-name/components";

or

final project CSS entrypoint

@import "tailwindcss"; @import "your-library-name/main.css";

your library packages.json

{ "exports": { "./main.css": "./main.css" } }

your library main.css

@source "./components";

Note: The advantage of main.css is that you can also ship custom @theme, @utility, and @custom-variant definitions.

However, applying this naively can introduce inefficiencies. A global @source reference to your entire UI library will cause Tailwind to generate styles for every file in the library, regardless of whether those components are actually used. Therefore, instead of recommending a single global @source, it is preferable for the consuming developer to include component-specific @source directives only for the components they use.

final project CSS entrypoint

@import "tailwindcss"; @source "./path/to/project-root/node_modules/your-library-name/components/Input.tsx"; @source "./path/to/project-root/node_modules/your-library-name/components/Calendar.tsx";

You can simplify this by providing a dedicated CSS file for each component in your UI library, where each CSS file internally references its corresponding component via a relative @source. In that case, the consuming project does not need to define @source manually; it is sufficient to import the CSS files of the components that are actually used.

final project CSS entrypoint

@import "tailwindcss"; @import "your-library-name/input.css"; @import "your-library-name/calendar.css";

your library packages.json

{ "exports": { "./input.css": "./input.css", "./calendar.css": "./calendar.css", "./button.css": "./button.css" } }

your library input.css

@source "./components/Input.tsx";

your library calendar.css

@source "./components/Calendar.tsx";

References:

All components from the UI package are included in the project's generated CSS, but I don't use every component TailwindCSS does not discover class names used in the NPM package Shipping a UI package alongside projects in a monorepo How to enable Tailwind CSS v4.0 for the packages/ui components in Turborepo?

Independently of this, you can still have a main.css, for example to provide a custom @theme color. Moreover, the color can remain overridable at the entry point.

final project CSS entrypoint

@import "tailwindcss"; @import "your-library-name/main.css"; @import "your-library-name/input.css"; @import "your-library-name/calendar.css"; /* @theme { --color-ui: #555; } */

your library packages.json

{ "exports": { "./main.css": "./main.css", "./input.css": "./input.css", "./calendar.css": "./calendar.css", "./button.css": "./button.css" } }

your library main.css

@theme { --color-ui: #000; }

your library input.css

@source "./components/Input.tsx";

your library calendar.css

@source "./components/Calendar.tsx";
Read Entire Article