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

@component-labs/react-showcase

v0.5.1

Published

A lightweight component showcase tool for React components

Readme

@component-labs/react-showcase

A lightweight, fast, and developer-friendly alternative to Storybook for showcasing React components. Built with Vite for instant HMR and minimal configuration.

Features

  • 🚀 Lightning fast - Powered by Vite
  • 📦 Zero config - Works out of the box with auto-detection
  • 🔥 Hot reload - Instant updates as you code
  • 🎛️ Interactive props - Control component props in real-time
  • 🎯 Type-safe - Full TypeScript support
  • 🎨 Dark mode - Built-in theme switching

Quick Start

1. Install the Package

Add Component Labs to your project using your preferred package manager:

npm install @component-labs/react-showcase
pnpm add @component-labs/react-showcase
yarn add @component-labs/react-showcase

That's it! The package will automatically build the CLI during installation via the postinstall hook.

2. Initialize Configuration

Create a showcase configuration file:

npx showcase init

This creates a showcase.config.ts file in your project root.

3. Run the Showcase

Start the development server:

npx showcase dev

The CLI will automatically build itself before starting if needed. Your showcase will open at http://localhost:6060

Alternative: Package Scripts

You can also add these to your package.json for easier access:

{
  "scripts": {
    "showcase": "showcase dev",
    "showcase:build": "showcase build"
  }
}

Then run with:

npm run showcase

Configuration

Edit showcase.config.ts to customize your showcase:

import { defineConfig } from "@component-labs/react-showcase/config";

export default defineConfig({
  // Pattern to match your showcase files
  include: ["src/**/*.showcase.{tsx,jsx}"],

  // Optional: Exclude certain paths
  exclude: ["node_modules/**", "dist/**"],

  // Optional: Custom title
  title: "My Component Library",

  // Optional: Port for dev server (default: 6060)
  port: 6060,
});

Creating Showcases

Basic Showcase

Create a file with the *.showcase.tsx extension:

import { YourComponent } from "./YourComponent";

// Define metadata
export default {
  title: "YourComponent",
};

// Create showcase variants
export function Basic() {
  return <YourComponent />;
}

export function WithProps() {
  return <YourComponent text="Hello World" />;
}

Interactive Controls

Add interactive props to let users experiment with your components:

import { Button } from "./Button";
import type { Props } from "@component-labs/react-showcase";

export default {
  title: "Button",
};

export function Interactive() {
  return (
    <Button variant="primary" size="medium">
      Click Me
    </Button>
  );
}

// Define interactive controls
Interactive.props = {
  variant: {
    type: "select",
    label: "Variant",
    default: "primary",
    options: ["primary", "secondary", "outline"],
  },
  size: {
    type: "select",
    label: "Size",
    default: "medium",
    options: ["small", "medium", "large"],
  },
  disabled: {
    type: "boolean",
    label: "Disabled",
    default: false,
  },
  children: {
    type: "string",
    label: "Text",
    default: "Click Me",
  },
} satisfies Props;

Available Prop Types

The showcase tool supports various control types:

  • string - Text input field
  • boolean - Checkbox toggle
  • number - Number input field
  • select - Dropdown with predefined options
  • object - JSON object editor (advanced)
  • array - Array editor (advanced)

CLI Commands

dev

Start the development server with hot reload:

npx showcase dev

Options:
  -p, --port <port>      Port to run the dev server on
  -c, --config <path>    Path to config file

build

Build the showcase for production deployment:

npx showcase build

Options:
  -c, --config <path>    Path to config file
  -o, --out-dir <path>   Output directory

init

Create a new showcase.config.ts file:

npx showcase init

Options:
  -f, --force    Overwrite existing config file

Example Files

The package includes complete example files that demonstrate best practices. You can find them in the examples/basic directory:

Button.tsx

A fully functional Button component with variants, sizes, and states:

import React from "react";

export interface ButtonProps {
  variant?: "primary" | "secondary" | "outline";
  size?: "small" | "medium" | "large";
  children: React.ReactNode;
  disabled?: boolean;
  onClick?: () => void;
}

export const Button: React.FC<ButtonProps> = ({
  variant = "primary",
  size = "medium",
  children,
  disabled = false,
  onClick,
}) => {
  const baseStyles =
    "rounded font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2";

  const variantStyles = {
    primary:
      "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500 disabled:bg-blue-300",
    secondary:
      "bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500 disabled:bg-gray-300",
    outline:
      "border-2 border-blue-600 text-blue-600 hover:bg-blue-50 focus:ring-blue-500 disabled:border-blue-300 disabled:text-blue-300",
  };

  const sizeStyles = {
    small: "px-3 py-1 text-sm",
    medium: "px-4 py-2 text-base",
    large: "px-6 py-3 text-lg",
  };

  return (
    <button
      className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]}`}
      disabled={disabled}
      onClick={onClick}
    >
      {children}
    </button>
  );
};

Button.showcase.tsx

Comprehensive showcase demonstrating 6 different use cases with interactive controls:

import { Button } from "./Button";
import type { Props } from "@component-labs/react-showcase";

export default {
  title: "Button",
};

export function Primary() {
  return <Button variant="primary">Click me</Button>;
}

export function Interactive() {
  return (
    <Button variant="primary" size="medium">
      Interactive Button
    </Button>
  );
}

Interactive.props = {
  variant: {
    type: "select",
    label: "Variant",
    default: "primary",
    options: ["primary", "secondary", "outline"],
  },
  size: {
    type: "select",
    label: "Size",
    default: "medium",
    options: ["small", "medium", "large"],
  },
  disabled: {
    type: "boolean",
    label: "Disabled",
    default: false,
  },
  children: {
    type: "string",
    label: "Button Text",
    default: "Interactive Button",
  },
} satisfies Props;

export function AllVariants() {
  return (
    <div className="flex gap-4">
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="outline">Outline</Button>
    </div>
  );
}

export function AllSizes() {
  return (
    <div className="flex gap-4 items-center">
      <Button size="small">Small</Button>
      <Button size="medium">Medium</Button>
      <Button size="large">Large</Button>
    </div>
  );
}

export function Disabled() {
  return (
    <div className="flex gap-4">
      <Button variant="primary" disabled>
        Disabled Primary
      </Button>
      <Button variant="secondary" disabled>
        Disabled Secondary
      </Button>
      <Button variant="outline" disabled>
        Disabled Outline
      </Button>
    </div>
  );
}

export function WithClickHandler() {
  const handleClick = () => {
    alert("Button clicked!");
  };

  return (
    <Button variant="primary" onClick={handleClick}>
      Click Me
    </Button>
  );
}

Best Practices

  • Naming Convention: Use *.showcase.tsx for all showcase files
  • Organization: Keep showcase files next to your components for easier maintenance
  • Multiple Variants: Create multiple exports to demonstrate different states and configurations
  • Interactive Props: Use prop controls to let users experiment with component behavior
  • Real Use Cases: Show practical examples of how components should be used in production
  • Documentation: Use descriptive names for showcase exports (e.g., DisabledState, WithIcon)

Deployment

Build and deploy to any static host:

npx showcase build
cd showcase-dist

Then deploy using your preferred platform:

Vercel

vercel

Netlify

netlify deploy --dir=showcase-dist --prod

GitHub Pages

# Add to .github/workflows/deploy.yml
- run: npx showcase build
- uses: peaceiris/actions-gh-pages@v3
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: ./showcase-dist

Compatible with:

  • Vercel
  • Netlify
  • GitHub Pages
  • Cloudflare Pages
  • AWS S3 + CloudFront

License

AGPL-3.0 © Benjamin Davies

Links