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

@johncomposed/rcup

v0.1.0-alpha.0

Published

A collection of UI plugins for React Cosmos

Downloads

29

Readme

@johncomposed/rcup

A collection of UI plugins for React Cosmos.

Plugins

| Plugin | Description | | ---------------- | --------------------------------------------------------------------------------------------------- | | slider-input | Range sliders in the control panel's Inputs section, created from fixtures with useFixtureSlider. | | theme-controls | A sun/moon dark mode toggle in the renderer toolbar, persisted across reloads. | | hello-world | Demo plugin and template: a renderer toolbar button that logs a configurable greeting. |

Installation

npm install -D @johncomposed/rcup

Enable all plugins at once in cosmos.config.json:

{
  "plugins": ["@johncomposed/rcup"]
}

Or enable individual plugins:

{
  "plugins": [
    "@johncomposed/rcup/plugins/slider-input",
    "@johncomposed/rcup/plugins/theme-controls",
    "@johncomposed/rcup/plugins/hello-world"
  ]
}

Don't mix the two forms — the package root already includes every plugin.

slider-input

Like useFixtureInput, but the value renders as a range slider in the playground's Inputs panel instead of a number field:

import { useFixtureSlider } from '@johncomposed/rcup/useFixtureSlider';

export default function MyFixture() {
  const [size, setSize] = useFixtureSlider('size', {
    defaultValue: 120,
    min: 40,
    max: 280,
    step: 1,
  });

  return <Box size={size} />;
}

min, max, and step are optional (defaults: 0, 100, 1). The hook returns [value, setValue] like useFixtureInput.

theme-controls

Adds a sun/moon toggle to the renderer toolbar. The chosen theme is written to Cosmos fixture state (and persisted by the playground's storage plugin); your fixtures decide how to apply it via a global decorator using the useThemeControls hook.

Add a cosmos.decorator.tsx to your root fixture folder:

import React from 'react';
import { useThemeControls } from '@johncomposed/rcup/useThemeControls';

export default function GlobalDecorator({ children }: { children: React.ReactNode }) {
  const { dark } = useThemeControls();

  React.useLayoutEffect(() => {
    // Or a data attribute, a context provider, a CSS variable...
    document.documentElement.classList.toggle('dark', dark);
    return () => document.documentElement.classList.remove('dark');
  }, [dark]);

  return children;
}

hello-world

A demo plugin kept as a template for new plugins: a toolbar button that logs a greeting configured via the ui.helloWorld section of cosmos.config.json:

| Key | Type | Default | Description | | ---------- | -------- | ---------------------------------- | -------------------------------------------------- | | greeting | string | "Hello from @johncomposed/rcup!" | Message logged when the toolbar button is clicked. |

Development

This repo includes a local Cosmos playground (vite-based, dev-only — none of it is published):

pnpm install
pnpm build        # or `pnpm dev` for watch mode
pnpm cosmos

Cosmos loads the built bundles from dist/, so rebuild (or keep pnpm dev running) and reload the browser to see plugin changes. Playground fixtures live in playground/.

How UI plugins work

UI plugin bundles are injected at run-time into the pre-bundled Cosmos UI, which exposes shared libraries as globals: react, react-dom, react-plugin, and styled-components must not be bundled — tsdown maps them onto those globals (see tsdown.config.ts). Renderer-side hooks (useFixtureSlider, useThemeControls) are ordinary library builds imported by fixtures through package subpaths.

Adding a plugin

  1. Create src/<camelName>/ with an index.tsx that calls createPlugin() + register(), and a spec.ts defining its name/config types.
  2. Import it from src/index.ts (the aggregate bundle).
  3. Add a uiPlugin({ <camelName>: 'src/<camelName>/index.tsx' }) entry in tsdown.config.ts. For renderer-side exports add a fixtureSide() entry plus a root subpath dir with a nested package.json (see useFixtureSlider/), and list it in package.json files.
  4. Add plugins/<kebab-name>/cosmos.plugin.json (+ a one-line package.json with "main": "./cosmos.plugin.json") so it can be enabled individually.
  5. Document it in this README.