TypeScript icon, indicating that this package has built-in type declarations

1.1.3 • Public • Published

React 18 Themes

test Maintainability codecov Version Downloads npm bundle size Get help Gitpod ready-to-code

🤟 👉 Unleash the Power of React Server Components

This project is inspired by next-themes. next-themes is an awesome package, however, it requires wrapping everything in a client side provider. And thus, it takes away all the benefits of Server Components.

react18-themes-lite removes this limitation and enables you to unleash the full power of React 18 Server Components. In addition, more features are coming up soon... Stay tuned!

  • ✅ Fully Treeshakable (import from react18-themes-lite/client/component)
  • ✅ Full TypeScript Support
  • ✅ Unleash the full power of React18 Server components
  • ✅ Works with all build systems/tools/frameworks for React18
  • ✅ Perfect dark mode in 2 lines of code
  • ✅ System setting with prefers-color-scheme
  • ✅ Themed browser UI with color-scheme
  • ✅ Support for Next.js 13 appDir
  • ✅ Sync theme across tabs and windows
  • ✅ Theme in sync with server component
  • ✅ Disable flashing when changing themes
  • ✅ Force pages to specific themes
  • ✅ Class or data attribute selector
  • ✅ Manipulate theme via useTheme hook

Check out the live example.


$ pnpm add react18-themes-lite
# or
$ npm install react18-themes-lite
# or
$ yarn add react18-themes-lite

Want Lite Version? npm bundle size Version Downloads

$ pnpm add react18-themes-lite-lite
# or
$ npm install react18-themes-lite-lite
# or
$ yarn add react18-themes-lite-lite

You need Zustand as a peer-dependency


With pages/

The best way is to add a Custom App to use by modifying _app as follows:

Adding dark mode support takes 2 lines of code:

import { ThemeSwitcher } from "react18-themes-lite";

function MyApp({ Component, pageProps }) {
	return (
			<ThemeSwitcher forcedTheme={Component.theme} />
			<Component {...pageProps} />

export default MyApp;

⚡🎉Boom! Just a couple of lines and your dark mode is ready!

Check out examples for advanced usage.

With app/

Update your app/layout.jsx to add ThemeSwitcher and ServerSideWrapper from react18-themes-lite. ServerSideWrapper is required to avoid flash of un-themed content on reload.

// app/layout.jsx
import { ThemeSwitcher } from "react18-themes-lite";
import { ServerSideWrapper } from "react18-themes-lite/server/nextjs";

export default function Layout({ children }) {
	return (
		<ServerSideWrapper tag="html" lang="en">
			<head />
				<ThemeSwitcher />

Woohoo! You just added dark mode and you can also use Server Component! Isn't that awesome!


That's it, your Next.js app fully supports dark mode, including System preference with prefers-color-scheme. The theme is also immediately synced between tabs. By default, react18-themes-lite modifies the data-theme attribute on the html element, which you can easily use to style your app:

:root {
	/* Your default theme */
	--background: white;
	--foreground: black;

[data-theme="dark"] {
	--background: black;
	--foreground: white;


In case your components need to know the current theme and be able to change it. The useTheme hook provides theme information:

import { useTheme } from "react18-themes-lite";

const ThemeChanger = () => {
	/* you can also improve performance by using selectors
	 * const [theme, setTheme] = useTheme(state => [state.theme, state.setTheme]);
	const { theme, setTheme } = useTheme();

	return (
			The current theme is: {theme}
			<button onClick={() => setTheme("light")}>Light Mode</button>
			<button onClick={() => setTheme("dark")}>Dark Mode</button>

Force per page theme and color-scheme

Next.js app router

import { ForceTheme } from "react18-themes-lite";

function MyPage() {
	return (
			<ForceTheme theme={"my-theme"} />

export default MyPage;

Next.js pages router

For pages router, you have 2 options. One is the same as the app router and the other option which is compatible with next-themes is to add theme to your page component as follows.

function MyPage() {
	return <>...</>;

MyPage.theme = "my-theme";

export default MyPage;

In a similar way, you can also force color scheme.

Forcing color scheme will apply your defaultDark or defaultLight theme, configurable via hooks.

Migrating from v0 to v1

  • defaultDarkTheme is renamed to darkTheme
  • setDefaultDarkTheme is renamed to setDarkTheme
  • defaultLightTheme is renamed to lightTheme
  • setDefaultLightTheme is renamed to setLightTheme



🤩 Don't forger to start this repo!

Want handson course for getting started with Turborepo? Check out React and Next.js with TypeScript



Licensed as MIT open source.

with 💖 by Mayank Kumar Chaudhari

Package Sidebar


npm i react18-themes-lite

Weekly Downloads






Unpacked Size

74.4 kB

Total Files


Last publish


  • mayank1513