<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Malahim Haseeb</title>
    <description>The latest articles on DEV Community by Malahim Haseeb (@malahim_haseeb_981126d794).</description>
    <link>https://dev.to/malahim_haseeb_981126d794</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3887390%2F550fe9f5-227e-491c-8a2b-04813c11cc0e.png</url>
      <title>DEV Community: Malahim Haseeb</title>
      <link>https://dev.to/malahim_haseeb_981126d794</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/malahim_haseeb_981126d794"/>
    <language>en</language>
    <item>
      <title>Tailwind CSS v4 — What Actually Changed (And What It Means for Your Next.js Project)</title>
      <dc:creator>Malahim Haseeb</dc:creator>
      <pubDate>Tue, 21 Apr 2026 04:21:12 +0000</pubDate>
      <link>https://dev.to/malahim_haseeb_981126d794/tailwind-css-v4-what-actually-changed-and-what-it-means-for-your-nextjs-project-472f</link>
      <guid>https://dev.to/malahim_haseeb_981126d794/tailwind-css-v4-what-actually-changed-and-what-it-means-for-your-nextjs-project-472f</guid>
      <description>&lt;p&gt;Tailwind v3 had a good run. Drop in &lt;code&gt;tailwind.config.js&lt;/code&gt;, point the &lt;code&gt;content&lt;/code&gt; array at your files, wire up PostCSS — done. Then &lt;strong&gt;v4 shipped in early 2025&lt;/strong&gt; and it's not an incremental update. It's a rethink.&lt;/p&gt;

&lt;p&gt;I've been running v4 in a real Next.js project (&lt;a href="https://blog.malahim.dev/project-showcases/quickpu-result-portal" rel="noopener noreferrer"&gt;QuickPU result portal&lt;/a&gt;) and this is what actually changed in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Biggest Shift — CSS-First Configuration
&lt;/h2&gt;

&lt;p&gt;In v3, your design system lived in JavaScript. In v4, it lives in CSS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v3 setup — two config files, PostCSS required:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// tailwind.config.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/**/*.{js,ts,jsx,tsx}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6366f1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// postcss.config.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tailwindcss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="na"&gt;autoprefixer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;v4 setup — one CSS file, zero JS config:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* globals.css */&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;62%&lt;/span&gt; &lt;span class="m"&gt;0.19&lt;/span&gt; &lt;span class="m"&gt;264&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--font-sans&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Inter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Content detection is automatic. No &lt;code&gt;content&lt;/code&gt; array. No missed files.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Your design tokens are no longer trapped in a JS build step — they're real CSS variables at runtime. DevTools can read them. Other CSS can reference them. The design system becomes part of the cascade.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Note for Next.js users:&lt;/em&gt; You still need a thin &lt;code&gt;postcss.config.mjs&lt;/code&gt; with &lt;code&gt;@tailwindcss/postcss&lt;/code&gt;. The "zero config" story is fully true for Vite — Next.js needs that one extra file.&lt;/p&gt;




&lt;h2&gt;
  
  
  oklch Colors — The Palette Is Different Now
&lt;/h2&gt;

&lt;p&gt;v4 ships with a brand-new default palette built in &lt;strong&gt;oklch&lt;/strong&gt; — a perceptually uniform color space that maps closer to how the human eye perceives color.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v3 — static hex at build time:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bg-blue-500&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3b82f6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;/* No CSS variable. No runtime access. */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;v4 — live CSS custom property:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--color-blue-500&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;62.3%&lt;/span&gt; &lt;span class="m"&gt;0.214&lt;/span&gt; &lt;span class="m"&gt;259&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.bg-blue-500&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color-blue-500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;/* Visible in DevTools. Overridable at runtime. */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two practical wins from this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dark mode gets simpler:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;98%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;15%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--color-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;12%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;95%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;/* One override. Everything updates automatically. */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Opacity modifiers always work:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* v3 — sometimes broke with CSS variables */&lt;/span&gt;
&lt;span class="nt"&gt;bg-blue-500&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;50&lt;/span&gt;  &lt;span class="c"&gt;/* unpredictable */&lt;/span&gt;

&lt;span class="c"&gt;/* v4 — oklch has a dedicated alpha channel */&lt;/span&gt;
&lt;span class="nt"&gt;bg-blue-500&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;50&lt;/span&gt;  &lt;span class="c"&gt;/* always correct */&lt;/span&gt;
&lt;span class="nt"&gt;bg-brand&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;30&lt;/span&gt;     &lt;span class="c"&gt;/* works on custom theme colors too */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The &lt;a class="mentioned-user" href="https://dev.to/theme"&gt;@theme&lt;/a&gt; Directive — Your Entire Design System in CSS
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@theme&lt;/code&gt; replaces &lt;code&gt;theme.extend&lt;/code&gt; entirely. Define CSS variables with the right naming prefix and Tailwind generates utilities automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* --color-* → bg-, text-, border-* utilities */&lt;/span&gt;
  &lt;span class="nt"&gt;--color-primary&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;oklch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;62&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;19&lt;/span&gt; &lt;span class="err"&gt;264&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--color-surface&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;oklch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;97&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;008&lt;/span&gt; &lt;span class="err"&gt;264&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="c"&gt;/* --spacing-* → p-, m-, gap-* utilities */&lt;/span&gt;
  &lt;span class="nt"&gt;--spacing-18&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* --font-* → font-* utilities */&lt;/span&gt;
  &lt;span class="nt"&gt;--font-display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Cal Sans"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;"Inter"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;sans-serif&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* --radius-* → rounded-* utilities */&lt;/span&gt;
  &lt;span class="nt"&gt;--radius-card&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* --shadow-* → shadow-* utilities */&lt;/span&gt;
  &lt;span class="nt"&gt;--shadow-card&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;oklch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="o"&gt;%),&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;16&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;oklch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;6&lt;/span&gt;&lt;span class="o"&gt;%);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* You can now use: bg-primary, p-18, font-display, rounded-card, shadow-card */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prefix is the convention. Tailwind reads it and generates the right utilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build Speed — The Oxide Engine
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;v3 (PostCSS)&lt;/th&gt;
&lt;th&gt;v4 (Oxide)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Full build&lt;/td&gt;
&lt;td&gt;~180ms&lt;/td&gt;
&lt;td&gt;~35ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incremental (HMR)&lt;/td&gt;
&lt;td&gt;~50–100ms&lt;/td&gt;
&lt;td&gt;&amp;lt;1ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The full build number (~5× faster) looks good in benchmarks. The HMR number is what you &lt;em&gt;feel&lt;/em&gt; every day — sub-millisecond on every save, compounding across hundreds of saves per session.&lt;/p&gt;

&lt;p&gt;What powers it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lightning CSS&lt;/strong&gt; — Rust-based CSS parser, replaces PostCSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic content detection&lt;/strong&gt; — no &lt;code&gt;content&lt;/code&gt; array, no missed files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental by design&lt;/strong&gt; — only reprocesses what changed&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  New Utilities Worth Knowing
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Utility&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;In v3?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;field-sizing-content&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Textarea auto-grows with content. No JS resize hack.&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;not-*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;not-hover:opacity-50&lt;/code&gt; — apply when variant is NOT active&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;inert&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Style elements with the &lt;code&gt;inert&lt;/code&gt; attribute&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;nth-child&lt;/code&gt; / &lt;code&gt;nth-last&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;nth-3:bg-muted&lt;/code&gt; — target specific children&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@container&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Container queries built in, no plugin needed&lt;/td&gt;
&lt;td&gt;Plugin only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;starting&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;@starting-style&lt;/code&gt; — animate from &lt;code&gt;display:none&lt;/code&gt; without JS&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@utility&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Custom utilities that work with &lt;code&gt;hover:&lt;/code&gt;, &lt;code&gt;dark:&lt;/code&gt;, &lt;code&gt;md:&lt;/code&gt; etc.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;@layer&lt;/code&gt; only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migrating a Real Next.js Project
&lt;/h2&gt;

&lt;p&gt;I migrated QuickPU from v3 to v4. The actual process:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tailwindcss @tailwindcss/postcss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// postcss.config.mjs&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tailwindcss/postcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — Update your CSS entry point:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Before (v3) */&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* After (v4) */&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;62%&lt;/span&gt; &lt;span class="m"&gt;0.19&lt;/span&gt; &lt;span class="m"&gt;264&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--font-sans&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Inter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* ...rest of your tokens */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3 — Run the official codemod:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @tailwindcss/upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It handles: config → &lt;code&gt;@theme&lt;/code&gt; conversion, &lt;code&gt;@tailwind&lt;/code&gt; → &lt;code&gt;@import&lt;/code&gt;, renamed utilities (&lt;code&gt;shadow-sm&lt;/code&gt; → &lt;code&gt;shadow-xs&lt;/code&gt;, etc.), deprecated class names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the codemod won't fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual regressions from renamed utilities — always do a UI pass after&lt;/li&gt;
&lt;li&gt;Third-party libraries (shadcn/ui, Headless UI) may need manual reconciliation with your &lt;code&gt;@theme&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Custom &lt;code&gt;plugin()&lt;/code&gt; functions — still work via compat mode, but &lt;code&gt;@utility&lt;/code&gt; / &lt;code&gt;@variant&lt;/code&gt; are the v4-native alternatives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a medium Next.js project: expect &lt;strong&gt;30–60 minutes&lt;/strong&gt;, not days.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should You Migrate?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stay on v3 if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You ship to production soon and it's already working — don't introduce risk&lt;/li&gt;
&lt;li&gt;A third-party UI library you depend on hasn't confirmed v4 compatibility&lt;/li&gt;
&lt;li&gt;You have extensive custom plugin logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Migrate to v4 if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starting a new project in 2025/2026 — no reason to start on v3&lt;/li&gt;
&lt;li&gt;You want design tokens as actual CSS variables (DevTools visibility, runtime theming)&lt;/li&gt;
&lt;li&gt;You're building a dark-mode-first or heavily themed UI&lt;/li&gt;
&lt;li&gt;HMR speed matters in your daily workflow&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;This is an architectural shift, not a version bump.&lt;/strong&gt; CSS-first config means your design system is part of the cascade — not a JS abstraction on top of it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;oklch is genuinely better than hex for UI work.&lt;/strong&gt; Perceptually uniform, P3-wide, and opacity always works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The codemod covers ~90% of migration.&lt;/strong&gt; Run it, do a visual pass, fix edge cases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New projects should start on v4 today.&lt;/strong&gt; The v3 config overhead is gone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&amp;lt;1ms HMR is the quiet win.&lt;/strong&gt; ~5× faster full builds looks good on paper, but sub-millisecond incremental is what changes your daily dev experience.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;Full post with side-by-side code comparisons and more detail on the QuickPU migration at &lt;a href="https://blog.malahim.dev/web-development/tailwind-css-v4-what-actually-changed-and-what-it-means-for-your-nextjs-project" rel="noopener noreferrer"&gt;blog.malahim.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Malahim Haseeb · AI &amp;amp; Full Stack Developer · &lt;a href="https://malahim.dev" rel="noopener noreferrer"&gt;malahim.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>nextjs</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Bun vs Node.js: The Runtime That Changes Everything in 2026</title>
      <dc:creator>Malahim Haseeb</dc:creator>
      <pubDate>Mon, 20 Apr 2026 01:13:36 +0000</pubDate>
      <link>https://dev.to/malahim_haseeb_981126d794/bun-vs-nodejs-the-runtime-that-changes-everything-in-2026-1gjo</link>
      <guid>https://dev.to/malahim_haseeb_981126d794/bun-vs-nodejs-the-runtime-that-changes-everything-in-2026-1gjo</guid>
      <description>&lt;p&gt;Bun vs Node.js: The Runtime That Changes Everything in 2026&lt;/p&gt;

&lt;p&gt;Visit: &lt;a href="https://blog.malahim.dev/web-development/bun-vs-nodejs-the-runtime-that-changes-everything-in-2026" rel="noopener noreferrer"&gt;https://blog.malahim.dev/web-development/bun-vs-nodejs-the-runtime-that-changes-everything-in-2026&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>NestJS vs Express vs Fastify: Which Should You Use in 2026?</title>
      <dc:creator>Malahim Haseeb</dc:creator>
      <pubDate>Sat, 18 Apr 2026 01:25:58 +0000</pubDate>
      <link>https://dev.to/malahim_haseeb_981126d794/nestjs-vs-express-vs-fastify-which-should-you-use-in-2026-5f8k</link>
      <guid>https://dev.to/malahim_haseeb_981126d794/nestjs-vs-express-vs-fastify-which-should-you-use-in-2026-5f8k</guid>
      <description>&lt;p&gt;NestJS vs Express vs Fastify: Which Should You Use in 2026?&lt;/p&gt;

&lt;p&gt;Visit: &lt;a href="https://blog.malahim.dev/web-development/nestjs-vs-express-vs-fastify-which-should-you-use-in-2026" rel="noopener noreferrer"&gt;https://blog.malahim.dev/web-development/nestjs-vs-express-vs-fastify-which-should-you-use-in-2026&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>Blazor vs React: Which One Should You Actually Use?</title>
      <dc:creator>Malahim Haseeb</dc:creator>
      <pubDate>Fri, 17 Apr 2026 07:18:05 +0000</pubDate>
      <link>https://dev.to/malahim_haseeb_981126d794/blazor-vs-react-which-one-should-you-actually-use-2c7j</link>
      <guid>https://dev.to/malahim_haseeb_981126d794/blazor-vs-react-which-one-should-you-actually-use-2c7j</guid>
      <description>&lt;p&gt;Blazor vs React: Which One Should You Actually Use?&lt;/p&gt;

&lt;p&gt;Visit: &lt;a href="https://blog.malahim.dev/web-development/blazor-vs-react-which-one-should-you-actually-use" rel="noopener noreferrer"&gt;https://blog.malahim.dev/web-development/blazor-vs-react-which-one-should-you-actually-use&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
  </channel>
</rss>
