Vite
Framework Guide

Vite

Complete guide to installing tweakcn/theme-picker themes in your Vite + React application. Uses a custom ThemeProvider without external dependencies.

Prerequisites

Vite 4+ with React
shadcn/ui initialized in your project
Tailwind CSS configured

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.json

Add 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.

index.htmlhtml
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>

The ThemeProvider is included

The CLI installs a custom ThemeProvider that uses data-theme attributes. It supports all tweakcn/theme-picker themes:

components/theme-provider.tsxtsx
1import { createContext, useContext, useEffect, useState } from "react"
2import { allThemeValues, DEFAULT_THEME } from "@/lib/themes-config"
3
4type ThemeProviderProps = {
5 children: React.ReactNode
6 defaultTheme?: string
7 storageKey?: string
8}
9
10type ThemeProviderState = {
11 theme: string
12 setTheme: (theme: string) => void
13}
14
15const ThemeProviderContext = createContext<ThemeProviderState>({
16 theme: DEFAULT_THEME,
17 setTheme: () => null,
18})
19
20export function ThemeProvider({
21 children,
22 defaultTheme = DEFAULT_THEME,
23 storageKey = "tweakcn-theme",
24}: ThemeProviderProps) {
25 const [theme, setTheme] = useState<string>(
26 () => localStorage.getItem(storageKey) || defaultTheme
27 )
28
29 useEffect(() => {
30 const root = document.documentElement
31 root.setAttribute("data-theme", theme)
32 }, [theme])
33
34 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}
46
47export const useTheme = () => useContext(ThemeProviderContext)

Wrap your app with ThemeProvider

Add the ThemeProvider to your root App component:

App.tsxtsx
1import { ThemeProvider } from "@/components/theme-provider"
2
3function App() {
4 return (
5 <ThemeProvider defaultTheme="default-dark">
6 {/* Your app content */}
7 </ThemeProvider>
8 )
9}
10
11export default App

Import theme styles

The CLI adds theme imports to your index.css. Make sure it includes:

index.csscss
1@tailwind base;
2@tailwind components;
3@tailwind utilities;
4
5/* tweakcn/theme-picker theme imports - added by CLI */
6@import "./styles/themes/index.css";
7
8@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:

Using the ThemeSwitchertsx
1import { ThemeSwitcher } from "@/components/theme-switcher"
2
3export 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.json

Replace theme-catppuccin with any theme: theme-claude, theme-vercel, etc.

Troubleshooting