Theme management with React 19 features - optimistic updates, cross-tab sync, and SSR support
npm install @codefast/themeTheme management with React 19 features - optimistic updates, cross-tab sync, and SSR support.
- 🚀 React 19 Optimized - Uses useOptimistic, useSyncExternalStore, useEffectEvent
- 🌗 System Theme Detection - Automatically detects and follows OS preference
- 🔄 Cross-tab Sync - Theme changes sync across all open tabs
- âš¡ Optimistic Updates - Immediate UI feedback during theme changes
- 🎯 SSR Ready - FOUC prevention with inline script
- 🔌 Framework Adapters - Built-in TanStack Start adapter, extensible for others
``bash`
pnpm add @codefast/theme
`tsx
// routes/__root.tsx
import { ThemeProvider, ThemeScript, resolveTheme } from '@codefast/theme';
import { getThemeServerFn, setThemeServerFn } from '@codefast/theme/tanstack-start';
export const Route = createRootRoute({
loader: async () => {
const theme = await getThemeServerFn();
return { theme };
},
component: RootComponent,
head: ({ loaderData }) => ({
scripts: [
{ tag: ThemeScript, props: { theme: loaderData?.theme ?? 'system' } },
],
}),
});
function RootComponent() {
const { theme } = Route.useLoaderData();
return (
persistTheme={(value) => setThemeServerFn({ data: value })}
>
);
}
`
`tsx
import { useTheme, themes } from '@codefast/theme';
function ThemeToggle() {
const { theme, setTheme, isPending } = useTheme();
return (
value={theme}
onChange={(e) => setTheme(e.target.value)}
disabled={isPending}
>
{themes.map((t) => (
))}
);
}
`
| Prop | Type | Description |
|------|------|-------------|
| theme | Theme | Initial theme value |persistTheme
| | (value: Theme) => Promise | Callback to persist theme |disableTransitionOnChange
| | boolean | Disable CSS transitions during theme change |nonce
| | string | CSP nonce for inline styles |
Returns ThemeContextType:
| Property | Type | Description |
|----------|------|-------------|
| theme | Theme | Current theme preference |resolvedTheme
| | ResolvedTheme | Resolved theme ('light' or 'dark') |setTheme
| | (value: Theme) => Promise | Set theme function |isPending
| | boolean` | Whether theme change is in progress |
MIT