nextjs•themes

Implement Dark and Light Theme in Next.js 16 with @wrksz/themes

A complete dark and light theme implementation in Next.js 16 using @wrksz/themes, React 19 and Tailwind CSS v4.

Next.jsReactTypeScriptTailwind CSSThemeDark Mode@wrksz/themes
By Hamid Mohamadi2026-08-31

Dark and Light Theme in Next.js 16 with @wrksz/themes

Modern applications should support comfortable experiences in both light and dark environments.

Theme handling looks simple from the outside, but a complete implementation requires managing theme state, system preferences, persistence, and hydration problems.

In a previous article, we implemented a theme system manually without dependencies. In this article, we will use @wrksz/themes to create a cleaner production-ready solution.

What We Will Build

The final system supports:

The flow:

User changes theme
        |
        v
@wrksz/themes manages state
        |
        v
HTML theme class changes
        |
        v
CSS variables update
        |
        v
Application UI updates

Project Stack

Installation

bun add lucide-react @wrksz/themes

Adding ThemeProvider

theme-provider.tsx
import { ThemeProvider } from '@wrksz/themes/next';
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  );
}

Creating Theme Toggle

theme-toggle.tsx
'use client';
 
import { useTheme } from '@wrksz/themes/client';
import { Moon, Sun } from 'lucide-react';
 
export function ThemeToggle() {
  const { resolvedTheme, setTheme } = useTheme();
 
  const isDark = resolvedTheme === 'dark';
 
  return (
    <button
      onClick={() => setTheme(isDark ? 'light' : 'dark')}
      className="hover:bg-muted rounded-full border p-3 transition"
      aria-label="Theme toggle"
    >
      {isDark ? <Moon size={20} /> : <Sun size={20} />}
    </button>
  );
}

Available Themes

The application supports:

System mode follows:

prefers-color-scheme

Tailwind CSS Integration

The active theme is applied through the HTML class:

<html class="dark"></html>

CSS variables can then define theme colors:

:root {
  --background: #ffffff;
}
 
.dark {
  --background: #10131c;
}

Components use semantic colors:

<div className="bg-background text-foreground">Content</div>

Hydration Handling

Theme systems can cause hydration mismatches because the server does not know the user's browser preference.

A server render and client render may initially differ.

@wrksz/themes provides Next.js integration to simplify this process.

Native Implementation vs @wrksz/themes

A native implementation is useful for learning:

Using @wrksz/themes provides:

Conclusion

Understanding how themes work internally is important.

However, production applications often benefit from using a dedicated solution.

@wrksz/themes provides a simple and maintainable way to add light, dark, and system themes to modern Next.js applications.