ADR-025: Tailwind CSS v4 Migration
Documents the completed migration from Tailwind CSS v3 to v4, replacing the tailwind.config.ts + @astrojs/tailwind setup with a CSS-native @theme inline configuration via the @tailwindcss/vite plugin.
Last updated
Status
Accepted (migration completed 2026-03-26) — supersedes ADR-002: Future CSS Tooling Considerations
Context
This ADR was originally written on 2026-02-18 as a decision to stay on Tailwind CSS v3 and defer the v4 upgrade. On 2026-03-26, the migration was performed. This document has been updated to reflect the completed state.
The original concerns from the deferred decision were:
@astrojs/tailwindis deprecated for v4 — resolved by switching to@tailwindcss/vite- Design token pipeline would break — resolved by using
@theme inlinein CSS, which references the existing--color-*CSS custom properties fromtokens/dist/tokens.css tailwind.config.tshas no equivalent — resolved; the file was deleted and all theme configuration lives insrc/styles/global.css@tailwindcss/typographycompatibility — resolved; v0.5.19 declares>=4.0.0-beta.1peer dependency support
Decision
Migrate to Tailwind CSS v4. All four preconditions from the original deferred decision were satisfied during the migration sprint.
What Changed
Integration
| Before | After |
|---|---|
@astrojs/tailwind v6.x integration | @tailwindcss/vite v4.2.2 Vite plugin |
tailwind.config.ts JS config file | Deleted — replaced by CSS |
@tailwind base/components/utilities | @import 'tailwindcss' |
Configuration model
Before: tailwind.config.ts loaded design tokens via a transformTokens() function that read tokens/dist/tailwind-tokens.json at build time.
After: src/styles/global.css uses @theme inline to map existing CSS custom properties (defined in tokens/dist/tokens.css) to Tailwind utility classes — no JSON import, no JS function:
@theme inline { --color-primary-500: hsl(var(--color-primary-500)); /* ... all tokens ... */}Using @theme inline (not @theme) is deliberate: it avoids creating new CSS custom properties that would conflict with the --color-* vars already defined in tokens/dist/tokens.css.
Dark mode
darkMode: "class" in the old JS config is replaced by a CSS variant declaration:
@variant dark (&:where(.dark, .dark *));Typography plugin
The JS config’s typography() function with CSS variable overrides is replaced by plain CSS in global.css:
@plugin "@tailwindcss/typography";
.prose { --tw-prose-body: hsl(var(--color-foreground-secondary)); --tw-prose-headings: hsl(var(--color-foreground-primary)); /* ... */}Custom utilities
The inline addUtilities plugin (focus-ring, focus-visible-ring, sr-only) is replaced by @utility blocks in global.css, using native CSS outline for focus rings (more accessible, works in Windows High Contrast mode).
Component @apply fix
Three component style blocks that used @apply with custom utility classes now include @reference to allow Tailwind to resolve utility names:
src/layouts/ProjectLayout.astrosrc/layouts/BlogLayout.astrosrc/pages/projects/index.astro
Class renames (automated by @tailwindcss/upgrade)
| Old | New |
|---|---|
bg-gradient-to-* | bg-linear-to-* |
flex-shrink-0 | shrink-0 |
flex-grow | grow |
outline-none (focus) | outline-hidden |
supports-[backdrop-filter]: | supports-backdrop-filter: |
Consequences
Positive
@astrojs/tailwinddeprecation resolved permanently- Build times significantly faster (Tailwind v4 uses a Rust-based engine: ~100x faster incremental builds)
- CSS configuration is now co-located in
src/styles/global.css— single source of truth for styling - Design token pipeline (
tokens/dist/tokens.css) unchanged — no migration of the build-tokens script required - Zero TypeScript errors after migration; 0 warnings from
astro check
Neutral
tailwindcss-themer(optional dependency) has a peer dependency warning against tailwindcss ^3. If theme switching features are used, this package needs to be replaced with v4-native theming (which has built-in multi-theme support via@variant). Update 2026-08-19: removed outright — no functional usage anywhere in the repo, and upstream never shipped tailwind-4 support (last publish 2024-11). Theming runs on design tokens + CSS custom properties (ADR-032, ADR-047).
References
- Tailwind CSS v4 Upgrade Guide
- Tailwind CSS v4 Release Blog
- Astro 5.2 Release Notes — Tailwind v4 support
- ADR-002: Future CSS Tooling Considerations — superseded
- ADR-000: Starter Template Architecture
Date: 2026-03-26
Participants: Template maintainers
Outcome: Completed