vartheme
MyApp
HomeDocs
Start
Active Theme
Default
Bundle Size
16.8kb
Zero dependencies
Quick Start
import { ThemeProvider }
from 'vartheme'

<ThemeProvider
theme="default"
>
Theme Toggle
🌙
Dark
Auto saved
Built-in Themes
Default
Ocean
Forest
Sunset
Rose
v0.1.6 — Now on npm

Dark mode for React, finally simple.

Zero config, CSS variable based theme switching. 5 beautiful themes. Animated toggle. 16.8kb.

$npm install vartheme

Everything you need, nothing you don't.

vartheme is focused, small, and does one thing really well — beautiful theming with zero effort.

Zero Config
No setup, no configuration. Just wrap your app and you're done.
🎨
5 Built-in Themes
Default, Ocean, Forest, Sunset, Rose — beautiful out of the box.
🌙
Animated Toggle
Smooth sun to moon animation. No external icon library needed.
💾
Persistent
Theme saved in localStorage. Survives page refresh automatically.
🖥️
System Detection
Detects OS dark/light preference and applies it automatically.
📦
16.8kb package
Tiny bundle size. Won't slow down your app. Zero dependencies.
🔷
TypeScript Ready
Full TypeScript support with types included out of the box.
🎯
CSS Variables
Auto injects CSS variables. Use them anywhere in your styles.
GitHub Stars
📦
/ month
npm Downloads
kb — actual
Bundle Size
🎯
Dependencies

Simple by design.

Get started in minutes. No boilerplate, no complexity.

01 — Install

BASH
1
npm install vartheme

02 — Wrap your app

TSX
1
import { ThemeProvider, ThemeToggle } from 'vartheme'
2
3
export default function App() {
4
return (
5
<ThemeProvider theme="ocean" mode="system" transitions>
6
<YourApp />
7
</ThemeProvider>
8
)
9
}

03 — Use the hook

TSX
1
import { useThemeContext } from 'vartheme'
2
3
function Navbar() {
4
const { resolvedMode, toggle, setTheme } = useThemeContext()
5
6
return (
7
<div>
8
<button onClick={toggle}>
9
{resolvedMode === 'dark' ? '☀️' : '🌙'}
10
</button>
11
<button onClick={() => setTheme('ocean')}>Ocean</button>
12
</div>
13
)
14
}

04 — Next.js SSR setup

TSX
1
// app/layout.tsx — Next.js SSR safe
2
import { getFOUCScript } from 'vartheme'
3
4
export default function RootLayout({ children }) {
5
return (
6
<html>
7
<head>
8
<script dangerouslySetInnerHTML={{ __html: getFOUCScript() }} />
9
</head>
10
<body>
11
<ThemeProvider>{children}</ThemeProvider>
12
</body>
13
</html>
14
)
15
}

05 — CSS variables

CSS
1
.card {
2
background: var(--vt-surface);
3
color: var(--vt-text);
4
border: 1px solid var(--vt-border);
5
}
6
7
.button {
8
background: var(--vt-primary);
9
color: white;
10
}

06 — shadcn/ui + Radix

TSX
1
// shadcn/ui + Radix support
2
<ThemeProvider strategy={{ type: 'class' }}>
3
{/* class="dark" set hoga automatically */}
4
</ThemeProvider>
5
6
// Custom attribute
7
<ThemeProvider strategy={{ type: 'data-attribute', attribute: 'data-mode' }}>