> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/BankkRoll/tweakcn-theme-picker/llms.txt
> Use this file to discover all available pages before exploring further.

# Vite Installation

> Install and configure tweakcn themes in your Vite React application

## Prerequisites

Before installing themes, ensure you have shadcn/ui set up in your Vite React project. If you haven't already:

<Steps>
  <Step title="Initialize shadcn/ui">
    ```bash theme={null}
    npx shadcn@latest init
    ```
  </Step>

  <Step title="Install required components">
    The theme system requires these shadcn/ui components:

    ```bash theme={null}
    npx shadcn@latest add dropdown-menu scroll-area button
    ```
  </Step>
</Steps>

## Installation

<Steps>
  <Step title="Install the theme system">
    Install the complete theme system with all 40+ themes:

    <CodeGroup>
      ```bash npm theme={null}
      npx shadcn@latest add https://tweakcn-picker.vercel.app/r/vite/theme-system
      ```

      ```bash yarn theme={null}
      yarn dlx shadcn@latest add https://tweakcn-picker.vercel.app/r/vite/theme-system
      ```

      ```bash pnpm theme={null}
      pnpm dlx shadcn@latest add https://tweakcn-picker.vercel.app/r/vite/theme-system
      ```
    </CodeGroup>

    This installs:

    * `lib/themes-config.ts` - Theme configuration and metadata
    * `components/theme-provider.tsx` - Custom React theme provider
    * `components/theme-switcher.tsx` - Interactive theme switcher UI
    * `styles/themes/*.css` - All 40+ theme CSS files
  </Step>

  <Step title="Add ThemeProvider to your app root">
    Wrap your application with the ThemeProvider in `src/App.tsx`:

    ```tsx src/App.tsx theme={null}
    import { ThemeProvider } from "@/components/theme-provider";
    import "@/styles/themes/index.css";

    function App() {
      return (
        <ThemeProvider>
          {/* Your app content */}
        </ThemeProvider>
      );
    }

    export default App;
    ```
  </Step>

  <Step title="Add the ThemeSwitcher to your UI">
    Import and use the ThemeSwitcher component anywhere in your app:

    ```tsx src/components/Header.tsx theme={null}
    import { ThemeSwitcher } from "@/components/theme-switcher";

    export function Header() {
      return (
        <header>
          <nav>
            {/* Your navigation */}
            <ThemeSwitcher />
          </nav>
        </header>
      );
    }
    ```
  </Step>
</Steps>

## How it works

The Vite adapter uses a **custom theme provider** with localStorage persistence:

<AccordionGroup>
  <Accordion title="Theme Provider implementation">
    Located at `components/theme-provider.tsx`:

    ```tsx theme={null}
    import { createContext, useContext, useEffect, useState } from "react";
    import { allThemeValues, DEFAULT_THEME } from "@/lib/themes-config";

    type ThemeProviderState = {
      theme: string;
      setTheme: (theme: string) => void;
    };

    const ThemeProviderContext = createContext<ThemeProviderState>({
      theme: DEFAULT_THEME,
      setTheme: () => null,
    });

    export function ThemeProvider({
      children,
      defaultTheme = DEFAULT_THEME,
      storageKey = "tweakcn-theme",
    }: {
      children: React.ReactNode;
      defaultTheme?: string;
      storageKey?: string;
    }) {
      const [theme, setTheme] = useState<string>(
        () => localStorage.getItem(storageKey) || defaultTheme,
      );

      useEffect(() => {
        const root = window.document.documentElement;
        root.setAttribute("data-theme", theme);
      }, [theme]);

      const value = {
        theme,
        setTheme: (theme: string) => {
          localStorage.setItem(storageKey, theme);
          setTheme(theme);
        },
      };

      return (
        <ThemeProviderContext.Provider value={value}>
          {children}
        </ThemeProviderContext.Provider>
      );
    }

    export const useTheme = () => {
      const context = useContext(ThemeProviderContext);
      if (context === undefined)
        throw new Error("useTheme must be used within a ThemeProvider");
      return context;
    };
    ```

    The provider manages theme state and automatically updates the `data-theme` attribute on the document root.
  </Accordion>

  <Accordion title="Theme configuration">
    All theme metadata is in `lib/themes-config.ts`:

    ```typescript theme={null}
    export interface ThemeConfig {
      name: string;          // e.g., "catppuccin"
      title: string;         // Display name
      primaryLight: string;  // Primary color in light mode
      primaryDark: string;   // Primary color in dark mode
      fontSans: string;      // Font family
    }

    export const themes: ThemeConfig[] = [
      {
        name: "vercel",
        title: "Vercel",
        primaryLight: "oklch(0 0 0)",
        primaryDark: "oklch(1 0 0)",
        fontSans: "Geist, sans-serif",
      },
      // ... 40+ more themes
    ];

    // Generate all theme values (name-light and name-dark)
    export const allThemeValues = themes.flatMap((t) => [
      `${t.name}-light`,
      `${t.name}-dark`,
    ]);
    ```
  </Accordion>

  <Accordion title="localStorage persistence">
    Themes are automatically saved to localStorage with the key `tweakcn-theme`:

    ```typescript theme={null}
    const setTheme = (theme: string) => {
      localStorage.setItem(storageKey, theme);
      setTheme(theme);
    };
    ```

    On page load, the theme is restored from localStorage:

    ```typescript theme={null}
    const [theme, setTheme] = useState<string>(
      () => localStorage.getItem(storageKey) || defaultTheme,
    );
    ```
  </Accordion>
</AccordionGroup>

## Adding individual themes

To install specific themes instead of all 40+:

<CodeGroup>
  ```bash Vercel theme theme={null}
  npx shadcn@latest add https://tweakcn-picker.vercel.app/r/theme-vercel
  ```

  ```bash Multiple themes theme={null}
  npx shadcn@latest add https://tweakcn-picker.vercel.app/r/theme-vercel
  npx shadcn@latest add https://tweakcn-picker.vercel.app/r/theme-github
  npx shadcn@latest add https://tweakcn-picker.vercel.app/r/theme-stripe
  ```
</CodeGroup>

Then import only the themes you need:

```css src/styles/themes/index.css theme={null}
@import "./vercel.css";
@import "./github.css";
@import "./stripe.css";
```

## Customizing themes

All theme CSS files are in `src/styles/themes/`. Each theme defines CSS variables:

```css src/styles/themes/vercel.css theme={null}
[data-theme="vercel-light"] {
  --background: oklch(1 0 0);
  --foreground: oklch(0 0 0);
  --primary: oklch(0 0 0);
  --primary-foreground: oklch(1 0 0);
  /* ... more variables */
}

[data-theme="vercel-dark"] {
  --background: oklch(0 0 0);
  --foreground: oklch(1 0 0);
  --primary: oklch(1 0 0);
  --primary-foreground: oklch(0 0 0);
  /* ... more variables */
}
```

Edit these files to customize colors, borders, shadows, and more.

## TypeScript usage

Use the `useTheme` hook from the theme provider:

```typescript theme={null}
import { useTheme } from "@/components/theme-provider";

function MyComponent() {
  const { theme, setTheme } = useTheme();
  
  return (
    <div>
      <p>Current theme: {theme}</p>
      <button onClick={() => setTheme("vercel-dark")}>
        Switch to Vercel Dark
      </button>
      <button onClick={() => setTheme("github-light")}>
        Switch to GitHub Light
      </button>
    </div>
  );
}
```

## Vite configuration

Ensure your `vite.config.ts` has path aliases configured:

```typescript vite.config.ts theme={null}
import path from "path";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
});
```

## Next steps

<CardGroup cols={2}>
  <Card title="Browse Themes" icon="palette" href="https://tweakcn-picker.vercel.app">
    Explore all 40+ available themes
  </Card>

  <Card title="Theme Picker" icon="eye-dropper" href="https://tweakcn-picker.vercel.app">
    Preview themes in real-time
  </Card>

  <Card title="Next.js Setup" icon="forward" href="/guides/nextjs">
    Install themes in Next.js
  </Card>

  <Card title="Remix Setup" icon="music" href="/guides/remix">
    Install themes in Remix
  </Card>
</CardGroup>
