Besharamcode

Creating a Dark Mode Toggle in React with Tailwind CSS v4

4/6/2025, 11:40:57 AM

Mohit Kushwah

Dark mode has become a must-have feature in modern web apps. With Tailwind CSS v4, enabling dark mode is simpler, cleaner—and different from earlier versions. In this guide, we’ll build a beautiful and functional Dark Mode Toggle in a React app using Tailwind v4 and Vite.

Step 1: Setting Up the Project

We’re using Vite for a fast development setup, with React and Tailwind CSS v4.

Install Dependencies

Run the following to set up Tailwind and its Vite plugin:

npm install tailwindcss @tailwindcss/vite

Configure Vite

In vite.config.js, import the Tailwind Vite plugin:

// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
});

Step 2: Enable Dark Mode in Tailwind v4

Tailwind v4 has removed the darkMode: 'class' option. Instead, we enable it via custom variants in the global CSS file.

Create or Edit index.css

@import "tailwindcss";

@custom-variant dark (&:where(.dark, .dark *));

This tells Tailwind to apply dark mode styles whenever an element or any of its children has the dark class.

Step 3: Create the Dark Mode Toggle Component

This component handles toggling and storing the user's dark mode preference.

// DarkToggle.jsx
import { useEffect, useState } from "react";

const DarkModeToggle = () => {
  const [darkMode, setDarkMode] = useState(() => {
    return localStorage.getItem("theme") === "dark";
  });

  useEffect(() => {
    const root = document.documentElement;
    if (darkMode) {
      root.classList.add("dark");
      localStorage.setItem("theme", "dark");
    } else {
      root.classList.remove("dark");
      localStorage.setItem("theme", "light");
    }
  }, [darkMode]);

  return (
    <button
      onClick={() => setDarkMode((prev) => !prev)}
      className="px-4 py-2 rounded-md bg-gray-200 dark:bg-gray-800 text-black dark:text-white shadow"
    >
      {darkMode ? "☀️ Light Mode" : "🌙 Dark Mode"}
    </button>
  );
};

export default DarkModeToggle;

Step 4: Use the Toggle in Your App

Now, plug the toggle button into your main app layout.

// App.jsx
import DarkModeToggle from "./DarkToggle";

export default function App() {
  return (
    <div className="min-h-screen flex flex-col items-center justify-center bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 transition-colors duration-300">
      <h1 className="text-3xl font-bold mb-6">Tailwind v4 Dark Mode</h1>
      <DarkModeToggle />
    </div>
  );
}

Final Touches

You can now style your entire app using dark: classes:

<div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
  {/* content */}
</div>

Add transition effects for smoother theme switching:

transition-colors duration-300

Conclusion

With just a few lines of code, you've added a dark mode toggle that:

  • Remembers the user's preference in localStorage
  • Uses Tailwind v4’s new @custom-variant system
  • Applies styles cleanly with dark: variants

Tailwind CSS v4 may feel different at first, but it offers greater flexibility. Now go ahead and make your UI shine (or dim 😄)!

Bonus Tips

  • Use icons like 🌙 and ☀️ for a better user experience.
  • Add animations with Tailwind’s transition and duration utilities.
  • You can extend dark mode to more components with ease using Tailwind’s dark: variant.

View the full repository and implementation here: https://github.com/besharamcode/toggle-theme-using-tailwind-css

Blog Visual

Leave a Comment

Comments: