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

react-theme-dynplug

v1.0.96

Published

A plugin-based theming system for React applications that separates themes as "style" and "layout". Provides headless theme switching component.

Downloads

2,529

Readme

React Theme Package

A powerful, plugin-based theming system for React applications that separates style (colors, effects) from layout (spacing, sizing).

Features

  • Plugin Architecture: Support for different styling libraries (Tailwind, Chakra, etc.) through adapters
  • Style vs Layout Separation: Independently control colors/effects and spacing/sizing
  • Zero Refactoring: Themes apply globally via CSS variables - no component changes needed
  • Headless UI: Fully customizable theme selector component
  • TypeScript: Full type safety
  • Local Storage: Automatically persists user preferences

Installation

Copy the theme-package directory into your project's src folder.

Quick Start

1. Configure Tailwind (if using Tailwind)

Update your tailwind.config.js to use theme CSS variables:

export default {
  theme: {
    extend: {
      colors: {
        primary: 'var(--color-primary)',
        secondary: 'var(--color-secondary)',
        accent: 'var(--color-accent)',
        background: 'var(--color-background)',
        surface: 'var(--color-surface)',
        text: 'var(--color-text)',
        'text-secondary': 'var(--color-text-secondary)',
        border: 'var(--color-border)',
      },
      spacing: {
        'theme-xs': 'var(--spacing-xs)',
        'theme-sm': 'var(--spacing-sm)',
        'theme-md': 'var(--spacing-md)',
        'theme-lg': 'var(--spacing-lg)',
        'theme-xl': 'var(--spacing-xl)',
        'theme-2xl': 'var(--spacing-2xl)',
      },
      borderRadius: {
        'theme-sm': 'var(--radius-sm)',
        'theme-md': 'var(--radius-md)',
        'theme-lg': 'var(--radius-lg)',
      },
      fontSize: {
        'theme-xs': 'var(--font-size-xs)',
        'theme-sm': 'var(--font-size-sm)',
        'theme-base': 'var(--font-size-base)',
        'theme-lg': 'var(--font-size-lg)',
      },
    },
  },
};

2. Wrap Your App

import { ThemeProvider, createTailwindPlugin, styles, layouts } from 'react-theme-dynplug';

const themeConfig = {
  styles,
  layouts,
  defaultStyle: 'ocean',
  defaultLayout: 'comfortable'
};

function Root() {
  return (
    <ThemeProvider config={themeConfig} plugins={[createTailwindPlugin()]}>
      <App />
    </ThemeProvider>
  );
}

3. Use Theme Classes

function MyComponent() {
  return (
    <div className="bg-surface p-theme-md rounded-theme-lg border border-border">
      <h1 className="text-theme-2xl text-text">Hello</h1>
      <p className="text-theme-base text-text-secondary">World</p>
    </div>
  );
}

4. Add Theme Selector

import { ThemeSelector } from 'react-theme-dynplug';

function ThemeSwitcher() {
  return (
    <ThemeSelector>
      {({ styles, layouts, currentStyle, currentLayout, selectStyle, selectLayout }) => (
        <div>
          <h3>Styles</h3>
          {styles.map(style => (
            <button
              key={style.id}
              onClick={() => selectStyle(style.id)}
              className={currentStyle.id === style.id ? 'active' : ''}
            >
              {style.name}
            </button>
          ))}

          <h3>Layouts</h3>
          {layouts.map(layout => (
            <button
              key={layout.id}
              onClick={() => selectLayout(layout.id)}
              className={currentLayout.id === layout.id ? 'active' : ''}
            >
              {layout.name}
            </button>
          ))}
        </div>
      )}
    </ThemeSelector>
  );
}

Creating Custom Themes

Custom Style

import type { ThemeStyle } from 'react-theme-dynplug';

export const myStyle: ThemeStyle = {
  id: 'my-style',
  name: 'My Custom Style',
  colors: {
    primary: '#3b82f6',
    secondary: '#8b5cf6',
    accent: '#ec4899',
    background: '#ffffff',
    surface: '#f9fafb',
    text: '#111827',
    text-secondary: '#6b7280',
    border: '#e5e7eb',
    error: '#ef4444',
    success: '#10b981',
    warning: '#f59e0b'
  },
  effects: {
    shadow: '0 4px 6px rgba(0,0,0,0.1)',
    blur: '8px'
  },
  animations: {
    duration: '200ms',
    timing: 'ease-in-out'
  }
};

Custom Layout

import type { ThemeLayout } from 'react-theme-dynplug';

export const myLayout: ThemeLayout = {
  id: 'my-layout',
  name: 'My Custom Layout',
  spacing: {
    xs: '0.25rem',
    sm: '0.5rem',
    md: '1rem',
    lg: '1.5rem',
    xl: '2rem',
    '2xl': '3rem'
  },
  sizing: {
    container: '1200px',
    component: {
      xs: '2rem',
      sm: '2.5rem',
      md: '3rem',
      lg: '3.5rem',
      xl: '4rem'
    }
  },
  borderRadius: {
    sm: '0.25rem',
    md: '0.5rem',
    lg: '0.75rem',
    full: '9999px'
  },
  typography: {
    fontSize: {
      xs: '0.75rem',
      sm: '0.875rem',
      base: '1rem',
      lg: '1.125rem',
      xl: '1.25rem',
      '2xl': '1.5rem',
      '3xl': '2rem'
    },
    lineHeight: {
      tight: '1.25',
      normal: '1.5',
      relaxed: '1.75'
    }
  }
};

Creating Custom Plugins

import type { ThemePlugin } from 'react-theme-dynplug';

export function createMyPlugin(): ThemePlugin {
  return {
    name: 'my-plugin',
    apply: (theme) => {
      // Apply theme to your library
      console.log('Applying theme:', theme);
    },
    cleanup: () => {
      // Clean up when theme changes
    }
  };
}

API Reference

ThemeProvider Props

  • config: ThemeConfig - Theme configuration with styles and layouts
  • plugins: ThemePlugin[] - Array of theme plugins
  • children: ReactNode - App content
  • storageKey: string - LocalStorage key (default: 'app-theme')

useTheme Hook

Returns:

  • currentStyle: Current active style
  • currentLayout: Current active layout
  • availableStyles: All available styles
  • availableLayouts: All available layouts
  • setStyle(id): Change active style
  • setLayout(id): Change active layout
  • currentTheme: Complete current theme object

ThemeSelector Component

Headless component for building custom theme selectors. Uses render props pattern.

Built-in Themes

Styles

  • Ocean: Cool blue tones
  • Sunset: Warm orange tones
  • Forest: Natural green tones
  • Midnight: Dark theme with purple accents

Layouts

  • Compact: Tight spacing, smaller text
  • Comfortable: Balanced spacing and sizing
  • Spacious: Generous spacing, larger text

License

MIT