fix: resolve Tailwind v4 missing utility classes in Docker builds on Mac OSX#2806
fix: resolve Tailwind v4 missing utility classes in Docker builds on Mac OSX#2806awschmeder wants to merge 1 commit intoHKUDS:mainfrom
Conversation
Two issues caused gap/spacing utility classes to be absent from the generated CSS bundle, breaking layout spacing throughout the UI. Issue 1 -- tailwind.config.js (v3-style) suppresses v4 utility scanner: When a v3 config is present alongside @tailwindcss/vite, the Tailwind v4 compiler's feature flags are set without the Utilities bit, so the content scanner never runs. Utility classes such as gap-1 through gap-6 are absent from the output. Fix: delete tailwind.config.js. Tailwind v4 is configured through CSS directives (@import, @source, @plugin in index.css) and does not use a JS config file. Issue 2 -- @tailwindcss/oxide misbehaves under Rosetta emulation: The frontend-builder stage in the Dockerfile ran as linux/amd64 on Apple Silicon hosts, causing @tailwindcss/oxide-linux-x64-gnu to run under Rosetta emulation. The native Rust scanner failed to traverse all source files in that environment, producing only .gap-px instead of the full set of gap utilities. Fix: add --platform=$BUILDPLATFORM to the frontend-builder stage so bun always runs on the host's native architecture. On Apple Silicon this uses the arm64 bun image natively; on linux/amd64 CI hosts $BUILDPLATFORM resolves to linux/amd64 and runs natively there too -- no regression for other users. Verified: after both fixes, bun run build produces index-BeS5t6hp.css containing .gap-1, .gap-2, .gap-3, .gap-4, .gap-6, and .gap-px.
danielaskdd
left a comment
There was a problem hiding this comment.
Thanks for digging into this. I agree there is likely a real Docker/platform-specific issue here, but I don't think the two changes have the same confidence level.
The Dockerfile change to run the frontend builder on --platform=$BUILDPLATFORM looks reasonable to me. If @tailwindcss/oxide was running under cross-arch emulation on Apple Silicon, forcing the builder stage onto the native build platform is a defensible fix and aligns with normal BuildKit usage.
I am less convinced by the tailwind.config.js deletion as currently justified.
LightRAG is already using Tailwind v4 CSS directives in src/index.css (@import, @source, @plugin), but there is no @config directive that explicitly loads tailwind.config.js. Per Tailwind v4 docs, a JavaScript config file is not applied implicitly in this setup. That makes the claim that the mere presence of the v3-style config disables the utility scanner hard to validate from the code shown here.
There is also a practical inconsistency in the current frontend setup: the repo still uses prose / dark:prose-invert classes in ChatMessage.tsx, while @tailwindcss/typography is only declared in tailwind.config.js, not via a v4 CSS @plugin directive. So removing tailwind.config.js without explicitly migrating any still-needed config/plugin behavior makes the configuration story less clear, not more.
My read is:
Dockerfilefix: likely correct and low-risk.tailwind.config.jsremoval: not yet convincingly proven as the root cause, and incomplete unless the remaining config/plugin needs are migrated or explicitly dropped.
I would recommend either:
- Split this PR and merge only the Docker/platform change first, or
- Keep the config discussion in this PR but prove the causality more directly and migrate any still-needed config/plugin behavior explicitly into the v4 CSS configuration.
For issue 2 specifically, I think the follow-up should be one of these two explicit directions:
- If the project wants to stay on Tailwind v4 CSS-first configuration, migrate the remaining config intentionally:
- add any required plugins via CSS directives, especially
@tailwindcss/typography - move any still-needed theme/customization out of
tailwind.config.js - then delete the JS config only after verifying
prose, spacing, and other custom utilities still build correctly
- add any required plugins via CSS directives, especially
- If the project still depends on the JS config, wire it in explicitly with
@configand verify whether the missing utilities are actually caused by config loading, source detection, or the cross-platform Docker environment
As written, issue 2 feels under-proven: it may be exposing a real v3/v4 config mismatch, but the PR doesn't yet demonstrate that deleting the file is the correct or complete fix.
Two issues caused gap/spacing utility classes to be absent from the generated CSS bundle, breaking layout spacing throughout the UI.
Issue 1 -- tailwind.config.js (v3-style) suppresses v4 utility scanner: When a v3 config is present alongside @tailwindcss/vite, the Tailwind v4 compiler's feature flags are set without the Utilities bit, so the content scanner never runs. Utility classes such as gap-1 through gap-6 are absent from the output. Fix: delete tailwind.config.js. Tailwind v4 is configured through CSS directives (@import, @source, @plugin in index.css) and does not use a JS config file.
Issue 2 -- @tailwindcss/oxide misbehaves under Rosetta emulation: The frontend-builder stage in the Dockerfile ran as linux/amd64 on Apple Silicon hosts, causing @tailwindcss/oxide-linux-x64-gnu to run under Rosetta emulation. The native Rust scanner failed to traverse all source files in that environment, producing only .gap-px instead of the full set of gap utilities. Fix: add --platform=$BUILDPLATFORM to the frontend-builder stage so bun always runs on the host's native architecture. On Apple Silicon this uses the arm64 bun image natively; on linux/amd64 CI hosts $BUILDPLATFORM resolves to linux/amd64 and runs natively there too -- no regression for other users.
Verified: after both fixes, bun run build produces index-BeS5t6hp.css containing .gap-1, .gap-2, .gap-3, .gap-4, .gap-6, and .gap-px.