-
Notifications
You must be signed in to change notification settings - Fork 80
tailwind v4 #481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
tailwind v4 #481
Conversation
WalkthroughReplaces Astro's Tailwind integration with a Vite-based Tailwind plugin, updates packages (Tailwind v4, Astro), removes legacy Tailwind config and several legacy CSS files, adds consolidated Changes
Sequence Diagram(s)sequenceDiagram
actor Dev as Developer
participant Astro as Astro app
participant Vite as Vite
participant TailwindVite as @tailwindcss/vite
participant CSS as Tailwind/CSS build
rect rgb(245,235,220)
Note over Astro,Vite: Old flow (removed)
Dev->>Astro: run build/dev
Astro->>Astro: invoke @astrojs/tailwind integration (removed)
Astro->>CSS: Tailwind processed using tailwind.config.ts
CSS-->>Astro: bundled styles
end
rect rgb(225,240,255)
Note over Vite,TailwindVite: New flow (current)
Dev->>Vite: run build/dev
Vite->>TailwindVite: load plugin (@tailwindcss/vite)
TailwindVite->>CSS: read `src/styles/global.css` (directives, @theme, plugins)
CSS-->>Vite: generate base/components/utilities (Tailwind v4)
Vite-->>Astro: serve/bundle generated styles with app
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for zero-to-nix ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (7)
src/components/mdx/NixStorePath.astro (1)
18-19: Tailwind v4 compatibility: prefer bracketed border width and verify custom tokens.
- Use border-[1.5px] instead of border-1.5 to avoid scale issues in v4.
- Ensure custom colors (light-gray, pale, cerulean, lilac) and bg-inherit/dark variants are defined in your @theme in global.css.
Apply:
- class="not-prose border-1.5 border-light-gray bg-pale dark:border-gray rounded-lg px-5 py-3 dark:bg-inherit" + class="not-prose border-[1.5px] border-light-gray bg-pale dark:border-gray rounded-lg px-5 py-3 dark:bg-inherit"As per Tailwind v4 notes.
Also applies to: 22-22
src/components/Link.astro (1)
30-33: Default no-underline can swallow caller intent; guard or document override.
- Callers (e.g., Features.astro) pass underline; this may not reliably win.
- Options:
- Document using underline! to override (important comes at end in v4: underline!).
- Or conditionally add no-underline only if caller didn’t request underline.
Proposed guard:
- <a {rel} {target} {...Astro.props} class="no-underline"> + <!-- Add above: const wantsUnderline = /\bunderline!?(\s|$)/.test((Astro.props.class ?? '')); --> + <a {rel} {target} {...Astro.props} class:list={[!wantsUnderline && 'no-underline', Astro.props.class]}>Please verify pages that require underlined links render correctly after this change. As per Tailwind v4 rules for the ! modifier.
Also applies to: 35-37
src/components/NixTerms.astro (1)
14-14: Use border-[1.5px] for v4 arbitrary width.Safer across v4 builds than border-1.5.
- class="border-1.5 border-light-gray hover:border-primary hover:bg-pale dark:border-gray dark:hover:border-primary dark:hover:bg-darker-gray rounded p-3 transition-colors duration-150 md:p-5 lg:p-7" + class="border-[1.5px] border-light-gray hover:border-primary hover:bg-pale dark:border-gray dark:hover:border-primary dark:hover:bg-darker-gray rounded p-3 transition-colors duration-150 md:p-5 lg:p-7"src/components/Features.astro (1)
29-30: Ensure underline wins against Link’s default no-underline.If Link applies no-underline by default, append underline! here (v4 important suffix) or adopt the conditional no-underline guard in Link.
- class="text-dark hover:text-primary dark:text-light-gray dark:hover:text-light-blue underline" + class="text-dark hover:text-primary dark:text-light-gray dark:hover:text-light-blue underline!"package.json (1)
27-29: @tailwindcss/vite should be moved to devDependencies; typography and prettier plugin versions are compatible with Tailwind v4.@tailwindcss/vite is a build-time tool and doesn't matter much in practice, but devDependencies is the semantically correct location. The typography plugin added explicit support for Tailwind v4 in recent releases, so update @tailwindcss/typography to a v4-compatible version; your pinned version 0.5.0-alpha.3 is appropriate. prettier-plugin-tailwindcss v0.6.11+ supports TypeScript configs and plugins when using v4, so v0.6.14 is compatible.
Recommended action: Move @tailwindcss/vite from dependencies to devDependencies.
src/components/mdx/H2.astro (1)
6-6: Remove redundant "no-underline" class from h2 element.The h2 wrapper does not need the
no-underlineclass since the Link component already applies it to the anchor element within. H2 elements do not naturally render with underlines—only the anchor text styling matters here.-<h2 {id} class="no-underline"> +<h2 {id}>src/styles/prose.css (1)
36-46: Consider reducing code duplication for inline code styling.The inline code styling (border, background, padding, dark mode) is duplicated between
.content code(lines 36-46) and.prose p, .content, h2, h3 { code }(lines 94-104). Consider extracting this into a shared mixin or custom property set if further duplication occurs.Example refactor using CSS custom properties:
@layer base { :root { --inline-code-border: 1px solid var(--light-gray); --inline-code-bg: var(--pale); --inline-code-padding: 0.125rem 0.375rem; --inline-code-radius: 0.25rem; } .dark { --inline-code-border: none; --inline-code-bg: var(--dark-gray); } .inline-code, .content code, .prose p code, .prose .content code, .prose h2 code, .prose h3 code { border: var(--inline-code-border); background-color: var(--inline-code-bg); padding: var(--inline-code-padding); border-radius: var(--inline-code-radius); } }Also applies to: 94-104
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (45)
astro.config.mjs(2 hunks)package.json(2 hunks)src/assets/css/main.css(0 hunks)src/assets/css/prose.css(0 hunks)src/assets/css/tailwind.css(0 hunks)src/assets/css/variables.css(0 hunks)src/components/Banner.astro(2 hunks)src/components/Breadcrumb.astro(1 hunks)src/components/CookieConsent.astro(2 hunks)src/components/Drawer.astro(3 hunks)src/components/DrawerToggler.astro(1 hunks)src/components/Dropdown.astro(2 hunks)src/components/ExternalSources.astro(1 hunks)src/components/Features.astro(1 hunks)src/components/FeedbackBar.astro(2 hunks)src/components/Footer.astro(3 hunks)src/components/Header.astro(1 hunks)src/components/HeaderLink.astro(1 hunks)src/components/Hero.astro(2 hunks)src/components/HorizontalContainer.astro(1 hunks)src/components/HoverableExternalSourceLink.astro(2 hunks)src/components/HoverableLink.astro(3 hunks)src/components/Link.astro(1 hunks)src/components/Navbar.astro(5 hunks)src/components/NixTerms.astro(1 hunks)src/components/PageSurvey.tsx(3 hunks)src/components/Pagination.astro(2 hunks)src/components/QuickStart.astro(2 hunks)src/components/Related.astro(1 hunks)src/components/Signup.astro(1 hunks)src/components/SignupModal.astro(2 hunks)src/components/Summary.astro(1 hunks)src/components/ThemeSwitcher.astro(2 hunks)src/components/mdx/Admonition.astro(4 hunks)src/components/mdx/H2.astro(1 hunks)src/components/mdx/Languages.astro(2 hunks)src/components/mdx/NixStorePath.astro(1 hunks)src/layouts/Layout.astro(2 hunks)src/pages/about.astro(1 hunks)src/pages/concepts/[slug].astro(1 hunks)src/pages/index.astro(4 hunks)src/pages/start/[slug].astro(1 hunks)src/styles/global.css(1 hunks)src/styles/prose.css(1 hunks)tailwind.config.ts(0 hunks)
💤 Files with no reviewable changes (5)
- src/assets/css/main.css
- src/assets/css/tailwind.css
- src/assets/css/variables.css
- tailwind.config.ts
- src/assets/css/prose.css
🧰 Additional context used
🪛 Biome (2.1.2)
src/styles/global.css
[error] 107-107: This @import is in the wrong position.
Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.
(lint/correctness/noInvalidPositionAtImportRule)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (34)
src/components/DrawerToggler.astro (1)
25-25: Class utility reordering is consistent and safe.The class attribute has been reordered for consistency across the codebase as part of the Tailwind v4 migration. Since utility order in the class attribute doesn't affect CSS output or rendering behavior, this change is purely presentational and aligns with the project's styling updates.
src/components/Breadcrumb.astro (1)
27-27: LGTM!The class reordering is cosmetic and doesn't affect the rendered output. In Tailwind, the order of utility classes in the HTML doesn't impact styling since CSS specificity is determined by the order in the generated stylesheet.
src/components/Related.astro (1)
15-15: LGTM! Class reordering is consistent with Tailwind v4 migration.The reordering of utility classes (moving hover states to the beginning) is purely organizational and doesn't affect functionality. The variant chaining in
dark:hover:text-light-grayis correct for Tailwind v4, applying dark mode first, then hover.src/components/ExternalSources.astro (1)
19-20: Custom utilities check after v4 migration.Class order change is fine. Also verify any custom utilities used nearby (e.g., remove-underline) are redefined in global.css under the new CSS‑first setup.
src/components/ThemeSwitcher.astro (1)
17-17: Verify custom utilities after Tailwind v4 migration.
- duration-hover isn’t a core Tailwind utility; confirm it’s redefined in global.css.
- Ensure text-yellow, text-dark-yellow, text-light-blue tokens exist via @theme.
Also applies to: 32-33
astro.config.mjs (1)
7-9: All verification checks passed—Tailwind/Vite setup is correct.CSS imports and @theme tokens are present in global.css; @tailwindcss/typography (0.5.0-alpha.3) is properly paired with v4; vite plugins correctly configure tailwindcss with typography plugin. No changes needed.
src/components/Hero.astro (1)
103-103: LGTM - Button styling preserved.The class reordering maintains the same visual styling while following a consistent ordering pattern used throughout the migration.
src/components/Dropdown.astro (1)
15-15: LGTM! Class reordering aligns with Tailwind v4 migration.The class order adjustments are purely cosmetic and don't affect functionality. All Tailwind v4 syntax requirements are met.
Also applies to: 24-24, 32-32
src/components/CookieConsent.astro (1)
12-12: LGTM! Class reordering aligns with Tailwind v4 migration.All class order adjustments are purely presentational and maintain the same functionality.
Also applies to: 26-26, 29-29, 35-35
src/components/SignupModal.astro (1)
11-11: LGTM! Class reordering aligns with Tailwind v4 migration.These class order adjustments are purely presentational.
Also applies to: 17-17
src/components/Drawer.astro (1)
30-30: LGTM! Class reordering aligns with Tailwind v4 migration.All class adjustments maintain the same functionality and follow Tailwind v4 conventions.
Also applies to: 43-43, 55-55
src/components/QuickStart.astro (2)
8-8: LGTM! Class reordering aligns with Tailwind v4 migration.The class adjustments are presentational only and maintain functionality.
Also applies to: 11-11, 26-26
14-16: Nice improvement! Enhanced user guidance.The added text explaining the "x" button functionality improves UX by clarifying that closing the notification affects all concept docs.
src/styles/global.css (3)
1-4: LGTM! Correct Tailwind v4 setup.The new import syntax and plugin configuration follow Tailwind v4 conventions correctly.
6-96: LGTM! Comprehensive theme configuration.The CSS custom properties and
@themeblock provide a solid foundation for the design system. The configuration correctly maps color tokens, border widths, transitions, and other design tokens for Tailwind v4.
98-105: LGTM! Component layer and utility styles.The prose code styling fix and banner-link utility are well-structured.
Also applies to: 109-121
src/components/PageSurvey.tsx (1)
48-48: LGTM! Class reordering aligns with Tailwind v4 migration.The className adjustments maintain the same functionality.
Also applies to: 56-56, 75-75
src/components/Pagination.astro (1)
34-34: LGTM! Class adjustments improve layout consistency.The reordering and addition of
flex justify-betweenutilities maintain proper functionality while improving the layout structure.Also applies to: 48-48
src/pages/about.astro (1)
23-23: Class reorder looks good.Purely presentational; no behavior change.
src/components/HeaderLink.astro (1)
17-17: No functional change.Whitespace-only; safe to keep.
src/components/Header.astro (1)
11-13: Formatting-only change.No behavioral impact.
src/pages/concepts/[slug].astro (1)
53-53: <!-- [scratchpad_start]
[task verify_review_comment]
Previous findings: xmax-w-none typo confirmed + opacity utilities found (ring-opacity-75, ring-opacity-5)
Current attempt: Failed to locate tailwind config/package.json via piped commands[observations]
- No output from fd/xargs pipe, likely command chain issue
- Need simpler direct approach to check tailwind version
- Original review asks only for typo verification in xmax-w-none
- But findings show additional v3 remnants that may need fixing
[pending]
- Confirm Tailwind v4 is actually in use (check package.json directly)
- Clarify scope: should new opacity utility issues be flagged?
[actions]
- Use simpler cat command on package.json directly
- Check if opacity utils are actual breakage or acceptable in this project's config
src/components/Banner.astro (2)
12-12: LGTM — class reordering only.
No behavior change.
30-30: No action required — custom utilityduration-hoveris properly defined.The custom utility is defined in src/styles/global.css at line 120 using
@applysyntax. The codebase consistently uses this utility across multiple components (Banner, Navbar, ThemeSwitcher, Footer, Dropdown), confirming it's a valid custom definition that extends Tailwind's default utilities.src/components/Navbar.astro (1)
32-33: LGTM — presentational-only reorders.Utility reordering aligns with Tailwind v4 migration; no behavioral changes observed.
Also applies to: 41-41, 51-51, 67-67, 88-88, 101-101
src/layouts/Layout.astro (2)
28-28: LGTM — class reordering only.
No behavior change.
7-7: ✓ Tailwind v4 setup verified.Global.css correctly imports Tailwind v4 and includes theme configuration. No issues found.
src/components/mdx/Languages.astro (1)
8-8: ****The
--graytoken is defined insrc/styles/global.css(line 19:--gray: #64748b;) and explicitly exposed in the@themeblock as--color-gray. Thedark:border-grayclass is valid and used consistently throughout the codebase (Signup.astro, PageSurvey.tsx, NixTerms.astro, HoverableExternalSourceLink.astro, Dropdown.astro, NixStorePath.astro, Languages.astro, and HoverableLink.astro). The pairing ofborder-soft-gray(light) +dark:border-gray(dark) is an established design pattern. No changes are required.Likely an incorrect or invalid review comment.
src/pages/index.astro (3)
26-31: LGTM! Consistent class ordering.The class reordering follows a logical pattern (color, size, weight, tracking, responsive) and is consistent with Tailwind v4 conventions.
47-49: LGTM! Hero button hover states properly configured.The addition of
hover:bg-orangeenhances the primary button interaction, and all hover variants follow Tailwind v4 syntax correctly.
67-77: LGTM! Proper variant ordering for dark mode hover states.The variant order
dark:hover:text-light-graycorrectly follows Tailwind v4's left-to-right evaluation (dark mode condition first, then hover state).src/components/mdx/Admonition.astro (2)
29-58: LGTM! Admonition container styling properly migrated to Tailwind v4.The class reordering and variant combinations (
dark:hover:bg-darker-gray) follow Tailwind v4's left-to-right evaluation correctly.
62-130: LGTM! Consistent icon class ordering.Icon classes have been consistently reordered from
size-* text-*totext-* size-*throughout the component, improving readability without affecting functionality.src/styles/prose.css (1)
1-47: Code uses correct Tailwind v4 syntax; no changes needed.Tailwind v4 still supports
@layer baseand Lightning CSS fully supports nested selectors. The@layer utilities→@utilitymigration applies only to utilities, not base styles. The nested syntax (.dark &) in lines 2-12 and 34-40 is correct and will work as expected with the v4 setup.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/components/Hero.astro(2 hunks)src/components/PageSurvey.tsx(3 hunks)src/components/SignupModal.astro(2 hunks)src/styles/global.css(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/components/SignupModal.astro
- src/components/Hero.astro
- src/components/PageSurvey.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-02T01:41:01.780Z
Learnt from: lucperkins
Repo: DeterminateSystems/zero-to-nix PR: 481
File: src/components/mdx/Languages.astro:19-19
Timestamp: 2025-11-02T01:41:01.780Z
Learning: In the zero-to-nix codebase, custom Tailwind border widths are defined in theme: --border-width-1\.5: 1.5px and --border-width-2\.5: 2.5px, making border-1.5 and border-2.5 valid utility classes.
Applied to files:
src/styles/global.css
🪛 Biome (2.1.2)
src/styles/global.css
[error] 98-98: This @import is in the wrong position.
Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.
(lint/correctness/noInvalidPositionAtImportRule)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (1)
src/styles/global.css (1)
120-120: Verify custom duration utilityduration-hoveris available.Line 120 applies a custom
duration-hoverclass defined via--transition-duration-hover: 200ms;at line 78. Verify that Tailwind v4 correctly generates this utility class from the theme variable. Standard Tailwind duration utilities use the patternduration-{ms}(e.g.,duration-200). Ifduration-hoveris not being generated, consider using a standard duration class or confirming the Tailwind v4 behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/styles/global.css (1)
1-3: Critical: Move@import "./prose.css"before@plugindirective.Per CSS specification, all
@importrules must precede other valid at-rules and style rules (except@charset). The current order places the prose import after the typography plugin, violating this requirement. Biome's linter confirms this violation withnoInvalidPositionAtImportRule.Apply this diff to correct the import order:
@import "tailwindcss"; +@import "./prose.css"; @plugin "@tailwindcss/typography"; -@import "./prose.css"; @custom-variant dark (&:where(.dark, .dark *));
🧹 Nitpick comments (1)
flake.nix (1)
62-65: Nice migration aid with a suggested enhancement.The deprecation script is a good UX touch for the pnpm → npm migration. Consider making the message more actionable:
- (script "pnpm" [ ] '' - echo "pnpm is no longer used in this repo; use npm instead" - exit 1 - '') + (script "pnpm" [ ] '' + echo "pnpm is no longer used in this repo." + echo "Use 'npm' commands instead, e.g., 'npm run dev' or 'npm ci'" + exit 1 + '')
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
package-lock.jsonis excluded by!**/package-lock.jsonpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
.npmrc(0 hunks).prettierignore(1 hunks)README.md(0 hunks)flake.nix(3 hunks)netlify.toml(1 hunks)pnpm-workspace.yaml(0 hunks)src/styles/global.css(1 hunks)
💤 Files with no reviewable changes (3)
- README.md
- .npmrc
- pnpm-workspace.yaml
✅ Files skipped from review due to trivial changes (2)
- .prettierignore
- netlify.toml
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-02T01:41:01.780Z
Learnt from: lucperkins
Repo: DeterminateSystems/zero-to-nix PR: 481
File: src/components/mdx/Languages.astro:19-19
Timestamp: 2025-11-02T01:41:01.780Z
Learning: In the zero-to-nix codebase, custom Tailwind border widths are defined in theme: --border-width-1\.5: 1.5px and --border-width-2\.5: 2.5px, making border-1.5 and border-2.5 valid utility classes.
Applied to files:
src/styles/global.css
🪛 Biome (2.1.2)
src/styles/global.css
[error] 3-3: This @import is in the wrong position.
Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.
(lint/correctness/noInvalidPositionAtImportRule)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (3)
src/styles/global.css (1)
118-120: Verifyduration-hoveris a valid utility or requires custom definition.The
.banner-linkutility referencesduration-hover, which appears to be a custom shorthand for the--transition-duration-hover: 200mstheme variable defined at line 79. Verify this is either a predefined Tailwind v4 utility or, if custom, confirm it's properly configured in the build setup (e.g., via Vite plugin or custom utilities).flake.nix (2)
47-47: Verify intentional use ofnodejs_latest.Using
nodejs_latestkeeps the development environment up-to-date but may introduce breaking changes when new Node.js versions are released. Consider whether pinning to a specific Node.js version (e.g.,nodejs_22) would provide more stability.
67-100: npm migration verified complete.All verification checks pass:
- package-lock.json exists
- pnpm-lock.yaml removed
- All required npm scripts present (build, dev, format, preview)
- The pnpm reference found in package-lock.json is from the astro dependency's
enginesfield, declaring optional package manager support—this is normal and does not affect npm functionalityThe migration to npm is complete and ready.
Summary by CodeRabbit
Chores
Style