Vite
Complete guide to installing tweakcn/theme-picker themes in your Vite + React application. Uses a custom ThemeProvider without external dependencies.
Prerequisites
Flash Prevention Setup
tweakcn/theme-picker uses data-theme attributes. To prevent flash on load, you need:
- :root fallback in CSS with your default theme colors
- Inline script in index.html to set data-theme before render
- Optional:
@media (prefers-color-scheme)for system preference support
Installation
Install the theme system
Run this single command to install the complete theme system for Vite. This includes all 42+ themes, a custom ThemeProvider, and all theme CSS.
$ pnpm dlx shadcn@latest add https://tweakcn-picker.vercel.app/r/vite/theme-system.jsonAdd flash prevention script to index.html
Add this inline script to your index.html before any other scripts. This applies the theme before React hydrates, preventing any flash.
1<!doctype html>2<html lang="en">3 <head>4 <meta charset="UTF-8" />5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />6 <title>My App</title>7 <!-- Flash Prevention: Apply theme before render -->8 <script>9 (function() {10 var stored = localStorage.getItem("tweakcn-theme");11 if (stored) {12 document.documentElement.setAttribute("data-theme", stored);13 } else {14 var isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;15 document.documentElement.setAttribute("data-theme", isDark ? "default-dark" : "default-light");16 }17 })();18 </script>19 </head>20 <body>21 <div id="root"></div>22 <script type="module" src="/src/main.tsx"></script>23 </body>24</html>data-theme immediately. This prevents flash because CSS variables are applied before the first paint.The ThemeProvider is included
The CLI installs a custom ThemeProvider that uses data-theme attributes. It supports all tweakcn/theme-picker themes:
1import { createContext, useContext, useEffect, useState } from "react"2import { allThemeValues, DEFAULT_THEME } from "@/lib/themes-config"34type ThemeProviderProps = {5 children: React.ReactNode6 defaultTheme?: string7 storageKey?: string8}910type ThemeProviderState = {11 theme: string12 setTheme: (theme: string) => void13}1415const ThemeProviderContext = createContext<ThemeProviderState>({16 theme: DEFAULT_THEME,17 setTheme: () => null,18})1920export function ThemeProvider({21 children,22 defaultTheme = DEFAULT_THEME,23 storageKey = "tweakcn-theme",24}: ThemeProviderProps) {25 const [theme, setTheme] = useState<string>(26 () => localStorage.getItem(storageKey) || defaultTheme27 )2829 useEffect(() => {30 const root = document.documentElement31 root.setAttribute("data-theme", theme)32 }, [theme])3334 return (35 <ThemeProviderContext.Provider value={{36 theme,37 setTheme: (t) => {38 localStorage.setItem(storageKey, t)39 setTheme(t)40 }41 }}>42 {children}43 </ThemeProviderContext.Provider>44 )45}4647export const useTheme = () => useContext(ThemeProviderContext)Wrap your app with ThemeProvider
Add the ThemeProvider to your root App component:
1import { ThemeProvider } from "@/components/theme-provider"23function App() {4 return (5 <ThemeProvider defaultTheme="default-dark">6 {/* Your app content */}7 </ThemeProvider>8 )9}1011export default AppImport theme styles
The CLI adds theme imports to your index.css. Make sure it includes:
1@tailwind base;2@tailwind components;3@tailwind utilities;45/* tweakcn/theme-picker theme imports - added by CLI */6@import "./styles/themes/index.css";78@layer base {9 * {10 @apply border-border;11 }12 body {13 @apply bg-background text-foreground;14 }15}Note: Keep your :root and .dark variable blocks as fallbacks to prevent flash of unstyled content.
Use the included ThemeSwitcher
The CLI installs a complete ThemeSwitcher component. Import and use it anywhere in your app:
1import { ThemeSwitcher } from "@/components/theme-switcher"23export function Header() {4 return (5 <header>6 <nav>{/* ... */}</nav>7 <ThemeSwitcher />8 </header>9 )10}The ThemeSwitcher includes a dropdown menu with all available themes, light/dark mode toggle, and displays the current theme with a color indicator.
Install Individual Themes
$ pnpm dlx shadcn@latest add https://tweakcn-picker.vercel.app/r/theme-catppuccin.jsonReplace theme-catppuccin with any theme: theme-claude, theme-vercel, etc.
ThemeProvider as shown above.