Dark mode

One attribute. The CSS works with JavaScript disabled, so ThemeProvider is only needed if you want a toggle.

The minimum

html
<html data-theme="dark">

That is the whole mechanism. The library's tokens carry a [data-theme="dark"] block, so every component follows.

With a toggle

import { ThemeProvider, ThemeToggle } from '@the_viveksingh/vivek-ui'

<ThemeProvider>
  <ThemeToggle mode="cycle" />
  {children}
</ThemeProvider>

mode="cycle" steps through light, dark and system. mode="toggle" flips between light and dark only, and never reaches system.

Preventing the flash

app/layout.tsx
import { themeScript } from '@the_viveksingh/vivek-ui'

<head>
  <script dangerouslySetInnerHTML={{ __html: themeScript }} />
</head>

themeScript is a build-time constant exported by the library, not user input. It reads storage, resolves system through matchMedia, and sets the attribute, all inside a try/catch, so a browser with storage disabled quietly gets the default. This site uses it: switch to dark, reload, and there is no flash.