AniUI Pro
Docs/Theming

Dark mode

Theming patterns for dark + light modes.

AniUI ships dark + light tokens out of the box. The library doesn't ship a toggle UI itself — that's a 5-line component on your end so you have full control over persistence and behavior.

How AniUI defines the modes

/* Light is the default */
:root {
  --background: 60 30% 98%;
  --foreground: 240 10% 4%;
  --primary: 240 6% 10%;
  /* ... */
}

/* Dark is opt-in via .dark class */
.dark {
  --background: 240 17% 4%;
  --foreground: 220 14% 96%;
  --primary: 239 84% 67%;
  /* ... */
}

Toggle between modes by adding/removing the dark class on <html>. Every component re-themes instantly because they consume the variables, not hard-coded colors.

Recommended: next-themes

On Next.js, next-themes handles persistence and avoids the flash-of-wrong-theme on first paint:

// app/providers.tsx
"use client";
import { ThemeProvider } from "next-themes";

export function Providers({ children }) {
  return (
    <ThemeProvider attribute="class" defaultTheme="dark" enableSystem={false}>
      {children}
    </ThemeProvider>
  );
}

Then a toggle is just useTheme():

import { useTheme } from "next-themes";

const { setTheme, resolvedTheme } = useTheme();
<button onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}>
  Toggle
</button>

Asset swaps for branding

Logos and illustrations that need an inverse for each mode: render both versions and swap with Tailwind's dark: variant. No JS state, no hydration churn:

<Image src={logoLight} className="block dark:hidden" />
<Image src={logoDark} className="hidden dark:block" />