DevDockTools

Add Dark Mode to Next.js with Tailwind CSS

Add dark mode to Next.js using Tailwind CSS: build a toggle button, persist the choice in localStorage, and style everything with dark: utility classes.

By Daniel Agrici4 min read
Next.jsTailwindCSSDark ModeCSSWeb Development

Dark mode has become a popular feature in web applications, allowing users to switch between a light and dark theme to reduce eye strain or improve readability. Implementing dark mode in a Next.js application can be achieved using a CSS framework like TailwindCSS.

Setting up TailwindCSS

To get started with TailwindCSS, you need to install it in your Next.js project using npm or yarn:

npm install tailwindcss

Then, create a tailwind.config.js file to configure the framework:

module.exports = {
  mode: 'jit',
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
}

This configuration tells TailwindCSS to use the "jit" mode, which compiles the CSS on demand, and to purge any unused classes from the pages and components directories.

Creating a Dark Mode Toggle

To create a dark mode toggle, you can add a button to your application's layout component:

import { useState, useEffect } from 'react';

function Layout({ children }) {
  const [darkMode, setDarkMode] = useState(false);

  useEffect(() => {
    const storedDarkMode = localStorage.getItem('darkMode');
    if (storedDarkMode === 'true') {
      setDarkMode(true);
    }
  }, []);

  const toggleDarkMode = () => {
    setDarkMode(!darkMode);
    localStorage.setItem('darkMode', darkMode ? 'false' : 'true');
  };

  return (
    <div className={darkMode ? 'dark' : ''}>
      <button onClick={toggleDarkMode}>Toggle Dark Mode</button>
      {children}
    </div>
  );
}

This code uses the useState hook to store the current dark mode state and the useEffect hook to persist the state in local storage.

Adding Dark Mode Styles

To add dark mode styles, you can create a styles/globals.css file:

@tailwind base;
@tailwind components;
@tailwind utilities;

.dark {
  @apply bg-gray-900 text-gray-100;
}

.dark a {
  @apply text-blue-500;
}

.dark a:hover {
  @apply text-blue-700;
}

This code uses the @apply directive to apply the dark mode styles to the .dark class.

System Preference or Manual Toggle: Which Fits Your App?

The toggle button above gives users explicit control, but it isn't always the right default. If your audience mostly wants the theme to match their OS setting without thinking about it, respect the prefers-color-scheme media query instead of forcing a manual choice on first visit — Tailwind's dark class strategy can still be driven by this media query rather than a stored preference.

A manual toggle makes sense for content-heavy apps (reading tools, code editors, dashboards used for long sessions) where users often want a theme that's different from their system-wide setting — someone might keep their OS in light mode but prefer a dark code editor. For marketing sites, docs, and anything users visit briefly, defaulting to system preference and skipping the toggle entirely is usually less friction.

Avoid building both a manual toggle and no persistence layer — that combination re-applies the "wrong" theme on every navigation and feels broken rather than helpful. If you do offer a toggle, treat "follow system" as a third state alongside light and dark, not just an initial default that gets overwritten the moment someone clicks.

Comparison of CSS Frameworks

Here's a comparison of popular CSS frameworks for implementing dark mode:

| Framework | Architecture | Class Naming Convention | Customizability | | --- | --- | --- | --- | | TailwindCSS | Utility-first | Low-level utility classes | High | | Bootstrap | Component-based | High-level component classes | Medium | | Material-UI | Component-based | High-level component classes | Medium | | Bulma | Component-based | High-level component classes | Medium |

As you can see, TailwindCSS provides the most customizability due to its utility-first architecture.

Using DevDockTools

To optimize your images for dark mode, you can use the image-resizer tool to resize your images and the jpg-compressor tool to compress them. You can also use the svg-optimizer tool to optimize your SVG icons.

To test your dark mode implementation, you can use the meta-tags-generator tool to generate meta tags for your application and the og-preview tool to preview your Open Graph metadata.

Next, you can test your application's dark mode implementation by switching between light and dark modes and verifying that the styles are applied correctly. You can also use the box-shadow-generator tool to generate box shadows for your elements and the gradient-generator tool to generate gradients for your backgrounds.

Frequently Asked Questions

How do I implement dark mode in Next.js?
You can implement dark mode in Next.js by using a CSS framework like TailwindCSS and adding a toggle button to switch between light and dark modes. You can also use the `useEffect` hook to persist the user's preference in local storage.
What is the difference between TailwindCSS and other CSS frameworks?
TailwindCSS is a utility-first CSS framework that provides low-level utility classes to style HTML elements, whereas other frameworks like Bootstrap provide high-level component classes. TailwindCSS is more customizable and flexible, but requires more setup.
Can I use dark mode with other CSS frameworks?
Yes, you can implement dark mode with other CSS frameworks like Bootstrap, Material-UI, or Bulma. However, the implementation details may vary depending on the framework's architecture and class naming conventions.