@wrksz/themesv2.1.1
Examples

Tailwind CSS

Using @wrksz/themes with Tailwind CSS v4 dark mode.

@wrksz/themes applies a dark class to <html> by default. In Tailwind v4, you need to tell Tailwind to use that class for dark: variants instead of the default prefers-color-scheme media query.

Try it

A card styled only with Tailwind classes and their dark: variants. The provider sets the class; Tailwind does the rest.

resolved …class …

Usage this month

Styled with Tailwind classes and their dark: variants.

UpgradeDetails
app/globals.css
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
usage-card.tsx
export function UsageCard() {
  return (
    <div className="bg-white text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100">
      <p className="text-zinc-500 dark:text-zinc-400">Usage this month</p>
      <div className="bg-zinc-100 dark:bg-zinc-800">
        <div className="bg-sky-500 dark:bg-sky-400" />
      </div>
    </div>
  );
}

Setup

Add @custom-variant to your CSS:

app/globals.css
@import "tailwindcss";

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

Then add to your root layout:

app/layout.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>
  );
}

Now use dark: variants anywhere:

<div className="bg-white text-black dark:bg-zinc-900 dark:text-white">
  Hello
</div>

Avoid @media (prefers-color-scheme) in CSS

If you manage CSS variables yourself (e.g. for custom themes), avoid using @media (prefers-color-scheme: dark) as a fallback:

AvoidThe media query applies before the theme class does, so it flashes
@media (prefers-color-scheme: dark) {
  :root:not(.light) {
    --bg: #09090b;
  }
}

The library reads prefers-color-scheme in the inline script and sets the correct class on <html> before the first paint. A CSS media query fallback is redundant and causes a flash for users whose system preference differs from their stored theme.

PreferClass-based selectors only
:root       { --bg: #ffffff; }
:root.dark  { --bg: #09090b; }

Data attribute

If you prefer attribute="data-theme" over classes, update the @custom-variant selector accordingly:

<ThemeProvider attribute="data-theme">
  {children}
</ThemeProvider>
app/global.css
@import "tailwindcss";

@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));

Custom themes

For more than two themes, use CSS variables per theme and reference them with Tailwind:

<ThemeProvider
  themes={["light", "dark", "dim"]}
  attribute="class"
>
  {children}
</ThemeProvider>
.light { --bg: #ffffff; --fg: #0a0a0a; }
.dark  { --bg: #09090b; --fg: #fafafa; }
.dim   { --bg: #1c1c1e; --fg: #fafafa; }
<div className="bg-(--bg) text-(--fg)">
  Hello
</div>