Skip to content

CSS & Tooling

Tailwind v4 vs v3 — Migration Notes from Production Sites

All articles
🎨 ⚡ 🔄

Production Shipping Experience

## What Tailwind v4 Actually Is Tailwind 4 dropped in December 2024 and it's the largest structural change since v2. Not just a feature bump — the core architecture shifted from PostCSS plugin to Vite plugin, the color system moved to oklch space, and the entire configuration model changed with the introduction of @theme. We shipped v4 on TradePilot (our trading dashboard) and deliberately kept v3 on Velocity (this template) because v3 still works fine and the migration risk wasn't worth the feature gain. After six months of running both in production, here's what's real and what's hype. ## The Five Wins **CSS Variables by Default.** Tailwind 4 generates all theme values as CSS custom properties. `tw-colors-blue-500` is now `var(--color-blue-500)` automatically. In v3 you had to manually enable this. On TradePilot we use this to swap token sets on runtime — dark mode, customer branding, seasonal themes. It's clean and performant. **oklch Color Space.** v4 defaults to oklch instead of sRGB. Colors shift slightly (usually towards better perceptual consistency), and the color palette is now editable in human-readable units: hue (0–360), saturation (0–100), lightness (0–100). We tuned TradePilot's accent color in oklch and immediately saw why designers prefer it — saturation adjustments feel less jarring across the scale. **Container Queries Out of the Box.** `@container` is now first-class syntax, no plugin required. You can do `@container (min-width: 30rem):` and Tailwind handles the container sizing. On Velocity we still use media queries because component breakpoints aren't necessary yet, but for complex card layouts inside sidebars, this saves you a refactor. **Vite Plugin over PostCSS.** The build pipeline is now deeply integrated with Vite. Incremental builds are faster. Rebuilds on CSS changes are nearly instant instead of a full PostCSS pass. On TradePilot the dev loop is noticeably snappier — saves maybe 500ms per save cycle, which matters when you're tweaking tokens. **No PostCSS Needed for Tailwind.** You can delete `postcss.config.js` in Tailwind-only projects. Less config, less magic. We ship TradePilot with zero PostCSS — just Vite + Tailwind. Simpler onboarding for new team members. ## The Four Traps **Config Format Breaks.** The `theme.extend` object format is unchanged, but how you *define* custom colors is different. In v3: `colors: { custom: '#000' }`. In v4: you define it in `@theme` in your CSS file. Mixing old and new config syntax works but feels janky. Our TradePilot build had a week of "why is this color not overriding" confusion until we restructured the config to be css-first. **Plugin Incompatibility.** Third-party Tailwind plugins compiled for v3 don't always work on v4. We use `@tailwindcss/forms` and `@tailwindcss/typography` — both were broken on first upgrade, fixed after a week. If you rely on older plugins (anything pre-2024), audit them before upgrading. **oklch Shifts Everything.** Colors won't match v3 pixel-for-pixel. The shift is usually 2–5%, but on brand sites where the hex color is a contract, this is a problem. We kept Velocity on v3 specifically because the Aidxn brand blue is locked to a precise hex value. Migrating would require re-approving brand colors with the design system owner. Not worth it for this template. **Build Cache Invalidation.** During the upgrade, old Tailwind cache persists and can conflict with the new v4 format. Delete `.next`, `dist`, and `.astro` folders before building. Took us a day to figure out why HMR was showing stale styles — turned out to be cache poison. ## The Migration Playbook If you're moving a 50–200 component codebase from v3 to v4: **Day 1: Prep.** Audit your custom plugins and third-party integrations. Make a list. Run `npm outdated` and pin versions that are known-good on v4. Back up your `tailwind.config.js` — you'll be rewriting it. **Day 2: Install and Break Everything.** Bump to v4, clear cache, run the build. Expect 15–40 visual regressions (colors, spacing, shadows). Don't panic — this is normal. Screenshot the homepage before and after so you have a visual diff. **Day 3–4: Config Refactor.** Move theme extensions from JavaScript config into `@theme` in your CSS entry point. This is the single biggest change. Instead of `theme: { extend: { colors: { ... } } }`, you write: ```css @theme { --color-custom-primary: oklch(/* ... */); } ``` If you have 20+ custom tokens, this takes half a day. The payoff: the CSS file is now the source of truth for design tokens. **Day 5: Color Audit.** Compare v3 and v4 output side by side. The oklch shift will be small but noticeable. Run a pixel test on critical pages. If brand colors are contractual, you have two choices: either accept the oklch shift, or pin specific colors to hex in @theme using `color()` space (non-standard but works). **Day 6: Test and Ship.** Run your test suite. Check that interactive components still work. Deploy to staging first. Monitor build times on CI/CD — they should improve. If not, you have a cache or plugin issue. Total time for a 100-component site: 2–5 days depending on custom theming complexity. ## Six FAQs **Q: Should I upgrade my v3 site right now?** A: Only if you have a specific feature need (container queries, oklch theming, CSS variables for runtime swaps). If v3 is working fine, stay on it. Upgrade is on a feature cadence, not a "gotta have latest" cadence. We didn't upgrade Velocity because v3 still works perfectly and the brand color constraint made it low-ROI. **Q: Will v4 be slower or faster?** A: Faster, but only if you're doing a full rebuild. Incremental builds are 30–50% faster thanks to Vite integration. On TradePilot the dev server restart went from ~2s to ~1s. **Q: Can I mix v3 and v4 in the same monorepo?** A: Yes, but don't. Each project gets its own node_modules and lockfile. The pain is during CI/CD when both need to build — slightly messier. We ran both on separate projects (TradePilot = v4, Velocity = v3) and that works cleanly. **Q: What if I have custom PostCSS plugins?** A: They still work, but you might not need them anymore. Tailwind 4 handles most of what people use PostCSS for. We had a custom plugin for brand token injection and scrapped it — done in @theme now. **Q: Do I need to change my HTML if I upgrade?** A: No. The class names are the same. Utility syntax is identical. Migration is purely config and CSS infrastructure. **Q: Will my Tailwind merge / classname conflicts break?** A: No. The compiler is smarter in v4 but still respects specificity and cascade. We had zero issues with `clsx` or dynamic class generation. ## The Verdict Tailwind 4 is legitimately better. The Vite integration is the quiet MVP — it's not flashy, but it makes dev feel faster. oklch colors are a win if you're doing sophisticated theming. Container queries are table stakes now that they're native CSS. But upgrading a production site isn't free. If your v3 site is stable and doesn't need the new features, the cost of migration outweighs the benefit. We use v4 on new projects and on TradePilot because the trading dashboard benefits from runtime token swapping. We keep Velocity on v3 because the template's job is to be a stable fork that runs everywhere, and v3 does that without ceremony. If you're building something new in 2026, start with v4. If you're maintaining a v3 site that's humming along, you don't need to move. Tailwind isn't going to drop v3 support anytime soon — they know the migration burden. Check out our full pricing page to see how we structure our site projects — we use v4 on modern dashboards and v3 on content templates like our Astro 5 review. The best version of Tailwind is the one you actually ship.
Let us make some quick suggestions?
Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.