npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mks2508/theme-manager-react

v3.6.2

Published

React hooks and components for theme management (shadcn/ui compatible, SSR-ready for Next.js, TanStack Start, Remix)

Downloads

511

Readme

@mks2508/theme-manager-react

React hooks and components for theme management (shadcn/ui compatible, Next.js 15 ready) with animated transitions

🚀 Features v3.3.0

  • Animated Theme Transitions: Smooth View Transitions API integration
  • Next.js Optimized: Dedicated /nextjs export for SSR/SSG
  • React 19 Compatible: Full support with TypeScript fixes
  • Flexible Dependencies: Compatible with wide range of peer dependency versions

📘 Quick Start Guide for Existing Next.js Projects

Prerequisites:

  • ✅ Next.js project configured
  • /public/themes/registry.json present
  • /public/themes/ folder with CSS theme files

Installation

npm install @mks2508/[email protected]

Setup in layout.tsx (App Router)

// app/layout.tsx
import { ThemeProvider } from '@mks2508/theme-manager-react/nextjs'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <ThemeProvider 
          registryUrl="/themes/registry.json"
          defaultTheme="default"
          defaultMode="auto"
          enableTransitions={true}
        >
          {children}
        </ThemeProvider>
      </body>
    </html>
  )
}

Sidebar with Animated Components

// components/Sidebar.tsx
import { 
  ModeToggle,
  AnimatedThemeToggler,
  ThemeSelector
} from '@mks2508/theme-manager-react/nextjs'

export function Sidebar() {
  return (
    <aside className="w-64 p-4">
      {/* Toggle light/dark with animations */}
      <ModeToggle />
      
      {/* Custom animated toggler */}
      <AnimatedThemeToggler direction="ltr">
        {({ effective, toggleTheme }) => (
          <button onClick={() => toggleTheme()}>
            {effective === 'light' ? '🌙' : '☀️'} Toggle
          </button>
        )}
      </AnimatedThemeToggler>
      
      {/* Full theme selector */}
      <ThemeSelector />
    </aside>
  )
}

Expected File Structure

/public/themes/
├── registry.json          ← Theme configuration
├── synthwave84-light.css  ← Individual themes
├── synthwave84-dark.css
├── rose-light.css
└── rose-dark.css

Registry.json Structure

{
  "themes": [
    {
      "id": "synthwave84",
      "name": "Synthwave84",
      "default": true,
      "modes": {
        "light": "/themes/synthwave84-light.css",
        "dark": "/themes/synthwave84-dark.css"
      }
    }
  ]
}

Full Installation (New Projects)

npm install @mks2508/theme-manager-react@^3.3.0
npm install @mks2508/shadcn-basecoat-theme-manager@^3.2.1

# Required peer dependencies (flexible versions)
npm install react react-dom
npm install @radix-ui/react-popover @radix-ui/react-dialog @radix-ui/react-tabs @radix-ui/react-switch @radix-ui/react-label
npm install lucide-react class-variance-authority clsx tailwind-merge

Pages Router Setup

// pages/_app.tsx
import { ThemeProvider } from '@mks2508/theme-manager-react/nextjs'
import type { AppProps } from 'next/app'
import './index.css'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <ThemeProvider
      registryUrl="/themes/registry.json"
      defaultTheme="default"
      defaultMode="auto"
      enableTransitions={true}
    >
      <Component {...pageProps} />
    </ThemeProvider>
  )
}

🎨 Animated Components

Animated Theme Toggler

import { AnimatedThemeToggler } from '@mks2508/theme-manager-react/nextjs'

export default function Navigation() {
  return (
    <nav>
      <AnimatedThemeToggler direction="ltr">
        {({ effective, toggleTheme, isAnimating }) => (
          <button 
            onClick={() => toggleTheme()}
            disabled={isAnimating}
            className="animated-toggle"
          >
            {effective === 'light' ? '🌙' : '☀️'}
          </button>
        )}
      </AnimatedThemeToggler>
    </nav>
  )
}

Animated Theme Selector

import { AnimatedThemeSelector } from '@mks2508/theme-manager-react/nextjs'

export default function ThemeGrid() {
  const themes = ['default', 'rose', 'blue', 'green']
  
  return (
    <div className="grid grid-cols-2 gap-4">
      {themes.map(theme => (
        <AnimatedThemeSelector 
          key={theme}
          targetTheme={theme}
          direction="ltr"
        >
          {({ switchToTheme, isCurrentTheme, isAnimating }) => (
            <button
              onClick={switchToTheme}
              disabled={isCurrentTheme || isAnimating}
              className={`theme-card ${isCurrentTheme ? 'active' : ''}`}
            >
              {theme} {isCurrentTheme && '✓'}
            </button>
          )}
        </AnimatedThemeSelector>
      ))}
    </div>
  )
}

Mode Toggle (Enhanced)

import { ModeToggle } from '@mks2508/theme-manager-react/nextjs'

export default function Header() {
  return (
    <header>
      <ModeToggle />
    </header>
  )
}

Theme Selector

import { ThemeSelector } from '@mks2508/theme-manager-react/nextjs'

export default function Sidebar() {
  return (
    <aside>
      <ThemeSelector 
        onThemeManagement={() => console.log('Open theme manager')}
        onFontSettings={() => console.log('Open font settings')}
      />
    </aside>
  )
}

Font Settings

import { FontSettingsModal } from '@mks2508/theme-manager-react'

export default function Settings() {
  return (
    <div>
      <FontSettingsModal />
    </div>
  )
}

Theme Management

import { ThemeManagementModal } from '@mks2508/theme-manager-react'

export default function Admin() {
  return (
    <div>
      <ThemeManagementModal />
    </div>
  )
}

Hooks

useTheme

import { useTheme } from '@mks2508/theme-manager-react/nextjs'

export default function CustomComponent() {
  const { 
    currentTheme, 
    currentMode,
    setTheme,
    themes,
    themeManager 
  } = useTheme()

  return (
    <div>
      <p>Current theme: {currentTheme}</p>
      <p>Current mode: {currentMode}</p>
      <button onClick={() => setTheme('rose', 'dark')}>
        Switch to Rose Dark
      </button>
      <p>Available themes: {themes.length}</p>
    </div>
  )
}

CSS Setup

Required CSS variables for theming:

@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  --secondary: 210 40% 96%;
  --secondary-foreground: 222.2 84% 4.9%;
  --muted: 210 40% 96%;
  --muted-foreground: 215.4 16.3% 46.9%;
  --accent: 210 40% 96%;
  --accent-foreground: 222.2 84% 4.9%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 210 40% 98%;
  --border: 214.3 31.8% 91.4%;
  --input: 214.3 31.8% 91.4%;
  --ring: 222.2 84% 4.9%;
  --radius: 0.5rem;
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  --primary: 210 40% 98%;
  --primary-foreground: 222.2 47.4% 11.2%;
  --secondary: 217.2 32.6% 17.5%;
  --secondary-foreground: 210 40% 98%;
  --muted: 217.2 32.6% 17.5%;
  --muted-foreground: 215 20.2% 65.1%;
  --accent: 217.2 32.6% 17.5%;
  --accent-foreground: 210 40% 98%;
  --destructive: 0 62.8% 30.6%;
  --destructive-foreground: 210 40% 98%;
  --border: 217.2 32.6% 17.5%;
  --input: 217.2 32.6% 17.5%;
  --ring: 212.7 26.8% 83.9%;
}

Compatibility Matrix

| Next.js Version | React Version | Router | Status | |----------------|---------------|---------|---------| | 15.x | 19.x | App Router | ✅ Recommended | | 15.x | 18.2+ | Pages Router | ✅ Fully Supported | | 15.x | 19.x | Pages Router | ✅ Supported | | 14.x | 18.x | Both | ✅ Legacy Support |

Known Issues & Workarounds

Radix UI Warnings with React 19

Some Radix UI components may show warnings in the console when using React 19. These are cosmetic and don't affect functionality:

Warning: useEffectEvent is not yet implemented
Warning: Accessing element.ref was removed in React 19

Workaround: These warnings are expected and will be resolved when Radix UI fully supports React 19.

TypeScript Strict Mode

If using strict TypeScript settings, you may need to add:

// tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

Migration Guides

From v3.2.x to v3.3.0

New Features:

  • ✅ Animated theme transitions with View Transitions API
  • ✅ New components: AnimatedThemeToggler, AnimatedThemeSelector
  • ✅ Enhanced ModeToggle with animations
  • ✅ Flexible peer dependencies

Update package.json:

- "@mks2508/theme-manager-react": "^3.2.1"
+ "@mks2508/theme-manager-react": "^3.3.0"

Update imports for Next.js:

- import { ThemeProvider } from '@mks2508/theme-manager-react'
+ import { ThemeProvider } from '@mks2508/theme-manager-react/nextjs'

From v3.0.0 to v3.3.0

- "@mks2508/theme-manager-react": "^3.0.0"
+ "@mks2508/theme-manager-react": "^3.3.0"

- "lucide-react": "^0.400.0"
+ "lucide-react": ">=0.400.0"

- "tailwind-merge": "^2.0.0"
+ "tailwind-merge": ">=1.0.0"

Support

  • React: 18.2+ or 19.x
  • Next.js: 14.x, 15.x
  • TypeScript: 5.x
  • Tailwind CSS: 3.x, 4.x

License

MIT

Author

MKS2508