FoundationsTheme

Theme

next-themes provider, toggle, and selector integrated with preferences.

The theme package wraps next-themes and syncs the active theme into the preferences storage key via applyThemePreference (no extra DOM writes).

When to use it

ExportUse when
ThemeProviderApp root — replaces raw next-themes provider
ThemeToggleIcon button cycling light/dark
ThemeSelectorLight / dark / system dropdown
ThemePreferenceSyncAdvanced: mount inside a custom provider

Installation

Registry CLI

Requires a one-time components.json registry entry for @feature-kit/theme.

pnpm dlx shadcn@latest add https://feature-kits.vercel.app/r/theme.json

Namespaced: npx shadcn@latest add @feature-kit/theme

Manual installation

Monorepo consumers can depend on workspace:* packages instead of the registry CLI.

pnpm add theme preferences ui

Dependencies

// apps/your-app/package.json
"dependencies": {
    "theme": "workspace:*"
    "preferences": "workspace:*"
    "ui": "workspace:*"
}

Transpile (Next.js)

// next.config.ts
transpilePackages: ["theme", "preferences", "ui"]

Import

import { ThemeProvider, ThemeToggle, ThemeSelector } from "@/lib/feature-kit/theme"

Usage

Replace the raw ThemeProvider from next-themes with the kit provider (already wired in the playground Providers):

import { ThemeProvider } from "theme"

<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
  {children}
</ThemeProvider>
Theme controls
`ThemeProvider` syncs with `preferences` via `applyThemePreference` on change.
Card surface
Muted surface
Secondary surface

ThemePreferenceSync runs automatically when syncPreferences is true (default). It mirrors light, dark, and system into the same localStorage key used by preferences bootstrap.

Live preview with sample data in the docs. Theme controls preview

On this page