tailwind v4 @theme colors work in apps/web but bg-brand-500 does nothing inside packages/ui Design Tokens
pnpm workspace, apps/web and packages/ui. The @theme block with my brand colours lives in apps/web/src/app.css and everything in the app renders correctly.
A Button in packages/ui/src/Button.tsx uses bg-brand-500. The class is in the DOM. There is no matching rule anywhere in the emitted stylesheet. Nothing errors, it just renders transparent.
packages/ui has its own ui.css with @import "tailwindcss" in it, which I inherited and have not thought about. Diagram of what I think is happening attached, tell me which half is wrong.
@pattern_tracer · 5d ago · 3 replies
Both halves are right and they are two separate bugs stacked on each other, which is why it is confusing.
First: v4 finds source files automatically starting from the project root of the stylesheet, and it skips
node_modules. In a pnpm workspace yourpackages/uiis reachable as a symlink insidenode_modules, so the scanner never opensButton.tsxand never learns thatbg-brand-500is wanted. Add an explicit source toapps/web/src/app.css:That path is relative to the CSS file, not the package root and not the repo root. Get that wrong and it fails silently, which is the second afternoon people lose to this.
Second: delete the
@import "tailwindcss"frompackages/ui/ui.css. Right now that produces a completely separate stylesheet that has never seen your@theme, so even when it does emit something, the token is not defined. Libraries inside a monorepo should ship class names and let the app compile. One compile, one token set, one output.Reply
Report
@lowell_frame · 2d ago
The symlink part is the bit that costs people the afternoon.
ls -l node_modules/@acmeand you will see it pointing straight back at../../packages/ui, and as far as the scanner is concerned that is node_modules and therefore not interesting.Reply
Report
@notetaking_ivo · 2d ago
One nuance if that package is also published to npm and consumed by apps outside this repo: those consumers cannot scan your source, so ship a prebuilt stylesheet for them and keep the source-scan path for the monorepo. Two consumers, two strategies, and it is fine to have both.
Reply
Report