fix(tailwind): load tailwind.config.js via @config - #2628
Conversation
Tailwind v4 does not read tailwind.config.js unless a CSS file asks for
it, so the theme.extend.fontSize entries in that file had never been
registered: text-2xs and text-3xs compiled to nothing.
Verified by building the app twice — with the directive the compiler emits
.text-2xs{font-size:.625rem} and .text-3xs{font-size:.5rem} for a probe
usage; without it, neither rule appears.
No call site uses either class today, so the emitted CSS is byte-identical
to master (161,345 bytes both ways). This only makes the two steps
available; nothing changes size.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🎩 PreviewA preview build has been created at: |
morgan-wowk
left a comment
There was a problem hiding this comment.
🤖 Agent review. Correct and byte-identical output today; one latent footgun worth weighing (inline).
| @@ -1,5 +1,7 @@ | |||
| @import "tailwindcss"; | |||
|
|
|||
| @config "../../tailwind.config.js"; | |||
There was a problem hiding this comment.
🤖 @config correctly loads the otherwise-dead tailwind.config.js (verified: no postcss config, nothing else references it, the path resolves, and tailwind 4.3.2 supports @config). Caveat: the legacy content glob in that config pins source detection to src/**/*.{js,jsx,ts,tsx}, so any class authored outside that glob (e.g. index.html, an .mjs/.mdx) will silently fail to compile — a review-invisible visual-regression class. And it currently only feeds text-2xs/text-3xs, which have zero usages in src. The v4-idiomatic alternative — moving those two values into the existing @theme inline block as --text-2xs/--text-3xs — avoids reintroducing a content array entirely. Worth considering instead.
tailwind.config.jshas been dead since the v4 upgrade. Tailwind v4 is CSS-first and does notauto-load a JS config — it only reads one when a stylesheet asks for it with
@config.src/styles/global.cssnever did, so the
theme.extend.fontSizeentries in that file were never registered andtext-2xs/text-3xscompiled to nothing.Proof the directive takes effect
A byte-identical build is ambiguous on its own — it is also what a silently-ignored directive looks
like. So I added a probe usage (
className="… text-2xs text-3xs") to a real component and built theapp both ways:
.text-2xs.text-3xs@configfont-size:.625rem✅font-size:.5rem✅@configThe probe was reverted; it is not part of this diff.
Proof nothing changes today
No file under
srcusestext-2xsortext-3xs— zero occurrences. With the probe removed, the builtstylesheet is byte-identical to
master:That also settles the one real risk in loading a legacy config: its
content: ["./src/**/*.{js,jsx,ts,tsx}"]key narrows source detection from v4's automatic scanning. Identical output over a full app build means
no currently-used class lives outside that glob. Worth knowing if a class is ever added to a
.html,.mdx, or.mjsfile — it would need adding tocontent.Why
@configrather than moving the values into@themeChosen per request. The alternative — deleting
tailwind.config.jsand adding--text-2xs: 0.625rem/--text-3xs: 0.5remto the existing@theme inlineblock — would be the more idiomatic v4 shape andwould leave one place to look for theme values instead of two. Happy to switch if preferred.
Context
Found while reviewing #2624, which independently discovered the same class of bug:
text-mdandfont-regularintypography.tsxalso emit no CSS, because--text-mdand--font-weight-regulararenot defined either. That one is a separate issue — those variants are referenced by every
<Text>in theapp, so defining them would change rendered output, unlike this change.
Reviewer checklist
@configis the direction, rather than folding the two steps into@theme inlinecontentglob is acceptable (see above)Validation
pnpm vite build✅ — output byte-identical tomasterpnpm prettier --check src/styles/global.css✅