theme

Light, dark and system themes with no flash on load, design tokens, and the components you copy into your app.

InterfaceClientBuilt onCSS variablesshadcn/ui
/play/theme/dark-mode
Pick a theme and the frame switches. Reload keeps your choice.

What it is

@kitr/theme gives your app light, dark and system themes with no flash on load, design tokens as CSS variables, and kitr ui add to copy components into your app.

Runs in the browser and during server rendering. For utility classes on the same tokens, add tailwind.

Install

kitr add theme

First time? Run npm i -g @kitr/kitr once. Inside a project, the global kitr runs your project's own version.

Adds @kitr/theme, its provider, config/theme.ts, app/styles/tokens.css and <ThemeScript /> in app/document.tsx. Adds react first if missing. Every change.

Quick start

useTheme() returns the current choice and the functions that change it:

// app/components/theme-button.tsx
import { useTheme } from '@kitr/theme'

export function ThemeButton() {
  const { resolved, toggle } = useTheme()
  return (
    <button type="button" onClick={toggle}>
      {resolved === 'dark' ? 'Switch to light' : 'Switch to dark'}
    </button>
  )
}

Click it and the page turns dark: <html> gets data-theme="dark" and every token switches. The choice is saved, so a reload keeps it. kitr ui add theme-toggle gives you a styled one. Next in the guide: Add a dark mode toggle.

Built on

Built on Role
CSS custom properties The tokens: colors, radii, spacing, with a dark set under [data-theme="dark"].
shadcn/ui-compatible registries The component format kitr ui add reads and copies into app/components/ui/.
class-variance-authority Component variants in the copied components.

kitr adds the provider, the no-flash script, the cookie for server rendering, typed tokens and the component registry.

Problems it solves

Further reading