Change Theme Color
CSS· 9 min read

Tailwind CSS v4: What's New and How I Use It — Moataseem Shaaban

Moataseem Shaaban breaks down Tailwind CSS v4's new features — the Rust-based engine, CSS-first configuration, OKLCH colors — and shows how he uses it on moataseem.com.

MS

Moataseem Shaaban

Full Stack Developer & Software Engineer

I'm Moataseem Shaaban, and Tailwind CSS v4 is a ground-up rewrite that fundamentally changes how you configure and use Tailwind. I adopted it early for my portfolio at moataseem.com, and it's now my go-to for every project. Built on a new Rust-based engine called Oxide, it's faster, simpler, and more powerful. Here's everything I've learned using it in production.

What Changed in v4?

The biggest shift is moving from JavaScript-based configuration to CSS-first configuration. Instead of a tailwind.config.js file, you define your design tokens directly in your CSS using the new @theme directive.

Performance: The Oxide Engine

Tailwind v4's new Rust-based engine delivers:

  • Up to 10x faster full builds compared to v3
  • Incremental builds in microseconds — changes reflect almost instantly
  • Smaller output CSS — better deduplication and tree shaking
  • Automatic content detection — no more configuring content paths

You no longer need to specify which files to scan. Tailwind v4 automatically detects your source files.

CSS-First Configuration

Before (v3 — tailwind.config.js):

javascript
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: '#10b981',
        background: '#0f172a',
      },
      borderRadius: {
        DEFAULT: '0.625rem',
      },
    },
  },
};

After (v4 — globals.css):

css
@import "tailwindcss";

@theme inline {
  --color-primary: oklch(0.7 0.15 160);
  --color-background: oklch(0.145 0 0);
  --radius: 0.625rem;
}

The @theme directive replaces the config file entirely. Your design tokens live alongside your styles, making it easier to see the full picture in one place.

OKLCH Color Space

Tailwind v4 embraces the OKLCH color space, which is a significant upgrade over HSL and hex colors.

Why OKLCH?

Perceptual uniformity: In HSL, a yellow at 50% lightness looks much brighter than a blue at 50% lightness. OKLCH fixes this — colors at the same lightness value actually look equally bright to human eyes.

css
/* These look equally bright in OKLCH */
--color-blue:   oklch(0.7 0.15 250);
--color-yellow: oklch(0.7 0.15 90);
--color-green:  oklch(0.7 0.15 160);

Defining Color Palettes

css
@theme inline {
  --color-primary: oklch(0.7 0.15 160);       /* Teal */
  --color-primary-light: oklch(0.85 0.1 160);
  --color-primary-dark: oklch(0.5 0.15 160);

  --color-destructive: oklch(0.7 0.19 22);     /* Red */
  --color-warning: oklch(0.8 0.15 85);         /* Amber */
  --color-success: oklch(0.7 0.15 145);        /* Green */
}

The three values are:

  • L (Lightness): 0 to 1
  • C (Chroma): 0 to ~0.4 (saturation)
  • H (Hue): 0 to 360 (color wheel angle)

New Features

Container Queries

Built-in support for container queries without plugins:

html
<div class="@container">
  <div class="@sm:grid-cols-2 @lg:grid-cols-3">
    <!-- Responsive to container width, not viewport -->
  </div>
</div>

3D Transforms

New utilities for 3D transformations:

html
<div class="rotate-x-45 rotate-y-12 perspective-800">
  <!-- 3D transformed element -->
</div>

Improved Gradient Support

Linear and radial gradients are more flexible:

html
<div class="bg-linear-to-r from-primary to-primary/0">
  <!-- Gradient that fades to transparent -->
</div>

Field Sizing

Automatic textarea sizing:

html
<textarea class="field-sizing-content" placeholder="Auto-growing textarea" />

Dark Mode

Dark mode in v4 uses CSS @media (prefers-color-scheme) by default, or you can use the class strategy:

css
@custom-variant dark (&:is(.dark *));

Then define dark mode values in your theme:

css
@theme inline {
  --color-background: oklch(1 0 0);          /* White in light mode */
  --color-foreground: oklch(0.145 0 0);      /* Near black */
}

.dark {
  --color-background: oklch(0.145 0 0);      /* Near black in dark mode */
  --color-foreground: oklch(0.985 0 0);      /* Near white */
}

Migration from v3

Step 1: Update Dependencies

bash
npm install tailwindcss@latest @tailwindcss/postcss@latest

Step 2: Update PostCSS Config

javascript
// postcss.config.mjs
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};

Step 3: Replace tailwind.config.js

Move your theme configuration from tailwind.config.js to your CSS file using @theme.

Step 4: Update Class Names

Some utilities have been renamed:

v3v4
bg-opacity-50bg-primary/50 (already in v3)
shadow-smshadow-xs
shadowshadow-sm
blurblur-sm
ringring-3
roundedrounded-sm

Step 5: Remove Config File

Once everything is migrated to CSS, delete tailwind.config.js.

PostCSS vs Vite Plugin

Tailwind v4 offers two integration paths:

javascript
// Option 1: PostCSS (works everywhere)
// postcss.config.mjs
export default { plugins: { '@tailwindcss/postcss': {} } };

// Option 2: Vite plugin (faster for Vite projects)
// vite.config.js
import tailwindcss from '@tailwindcss/vite';
export default { plugins: [tailwindcss()] };

For Next.js projects, use the PostCSS approach.

Conclusion

Tailwind CSS v4 is a major leap forward. The CSS-first configuration is more intuitive, the Oxide engine is blazingly fast, and features like OKLCH colors and container queries make it the most capable version yet. On moataseem.com, it powers every component with minimal CSS overhead.

If you're starting a new project, use v4 from day one. If you're on v3, the migration is straightforward — mostly renaming utilities and moving your config to CSS.

— Moataseem Shaaban, Full Stack Developer & Software Engineer. Follow my work at moataseem.com.

MS
Loading0%
Initializing portfolio...