better-themes

Quick Start

Get started with better-themes in minutes

Basic Setup

Wrap your app with ThemeProvider

The ThemeProvider component should be placed at the root of your application:

layout.tsx
import { ThemeProvider } from "better-themes";

function Layout({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider>
      {children}
    </ThemeProvider>
  );
}

Add suppressHydrationWarning to your <html> tag

This prevents hydration warnings when the theme is applied:

layout.tsx
<html lang="en" suppressHydrationWarning>
  <body>
    <ThemeProvider>
      {children}
    </ThemeProvider>
  </body>
</html>

Style your app

By default, ThemeProvider sets a class attribute on the <html> element. Style your app with CSS:

global.css
:root {
  --background: white;
  --foreground: black;
}

.dark {
  --background: black;
  --foreground: white;
}

Or use hard-coded values:

global.css
html,
body {
  color: #000;
  background: #fff;
}

.dark,
.dark body {
  color: #fff;
  background: #000;
}

Using the Theme

Access the current theme and change it with the useTheme hook:

theme-switcher.tsx
import { useTheme } from "better-themes";

function theme-switcher() {
  const { theme, setTheme, themes } = useTheme();

  return (
    <div>
      <p>Current theme: {theme}</p>
      <button onClick={() => setTheme("light")}>Light</button>
      <button onClick={() => setTheme("dark")}>Dark</button>
      <button onClick={() => setTheme("system")}>System</button>
    </div>
  );
}

Tailwind CSS

For Tailwind CSS, use class-based dark mode:

layout.tsx
<ThemeProvider attribute="class">
  {children}
</ThemeProvider>

Then use Tailwind's dark mode classes:

page.tsx
<h1 className="text-black dark:text-white">
  Hello
</h1>

Important Notes

  • The theme value is undefined on the server. Only use it after the component mounts on the client.
  • See the SSR Guide for details on handling server-side rendering.
  • Check out Framework Guides for framework-specific setup instructions.

On this page