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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@projectdiscoveryio/pd-design-system

v0.0.3

Published

A modern design system built with React, TypeScript, Tailwind CSS, shadcn/ui, and Radix UI

Readme

PD Design System

A modern, production-ready design system built with React, TypeScript, Tailwind CSS, shadcn/ui, and Radix UI primitives.

🚀 Features

  • React 18 & 19 with TypeScript
  • Tailwind CSS for styling
  • TypeScript-based Design Tokens with auto-generated CSS
  • shadcn/ui components (customizable)
  • Radix UI primitives for accessibility
  • Storybook 8 for component documentation
  • Tree-shakeable ESM/CJS builds
  • Type-safe with full TypeScript support
  • Dark mode support built-in
  • CVA (Class Variance Authority) for component variants

📦 Installation

From npm (Recommended)

npm install @projectdiscovery/pd-design-system
# or
yarn add @projectdiscovery/pd-design-system
# or
pnpm add @projectdiscovery/pd-design-system

Local Development / Git

# From local directory
npm install file:../path/to/pd-design-system

# From GitHub
npm install git+https://github.com/projectdiscovery/pd-design-system.git

Setup Tailwind CSS

Since this design system uses Tailwind CSS, you need to configure it in your consuming application:

1. Install Tailwind CSS (if not already installed):

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

2. Update your tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx}",
    // 🔥 IMPORTANT: Include design system components
    "./node_modules/@projectdiscovery/pd-design-system/dist/**/*.{js,mjs}",
  ],
  darkMode: "class", // 🔥 REQUIRED for theme switching
  theme: {
    extend: {},
  },
  plugins: [],
};

3. Import the design system styles in your main CSS/entry file:

/* app/globals.css or src/index.css */
@import "@projectdiscovery/pd-design-system/styles.css";

Or import in your main TypeScript/JavaScript file:

// main.tsx or App.tsx
import "@projectdiscovery/pd-design-system/styles.css";

🎨 Usage

Step 1: Wrap with ThemeProvider (REQUIRED)

// app/layout.tsx or App.tsx
import { ThemeProvider } from "@projectdiscovery/pd-design-system";
import "@projectdiscovery/pd-design-system/styles.css";

export default function App() {
  return (
    <ThemeProvider>
      <YourApp />
    </ThemeProvider>
  );
}

Step 2: Use Components with Type-Safe Colors

import {
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardContent,
  Input,
} from "@projectdiscovery/pd-design-system";

function MyComponent() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Welcome</CardTitle>
      </CardHeader>
      <CardContent>
        <Input placeholder="Enter your name" />

        {/* Use built-in variants */}
        <Button variant="default">Submit</Button>

        {/* Or use custom colors from theme (with autocomplete!) */}
        <Button bgColor="green">Success</Button>
        <Button bgColor="colors.blue.600">Custom Blue</Button>
      </CardContent>
    </Card>
  );
}

Button Usage

import { Button } from "@projectdiscovery/pd-design-system";

{/* Built-in variants */}
<Button variant="default">Default</Button>
<Button variant="destructive">Delete</Button>
<Button variant="success">Success</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>

{/* Custom colors from theme (TypeScript autocomplete!) */}
<Button bgColor="green">Green Button</Button>
<Button bgColor="red">Red Button</Button>
<Button bgColor="colors.blue.700">Deep Blue</Button>

{/* Sizes */}
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>

{/* ❌ className is NOT available (design system controls styling) */}
<Button className="custom">Won't work</Button>

Card Component

import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
  Button,
} from "@projectdiscovery/pd-design-system";

<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Card description goes here</CardDescription>
  </CardHeader>
  <CardContent>
    <p>Card content</p>
  </CardContent>
  <CardFooter>
    <Button>Action</Button>
  </CardFooter>
</Card>;

Input Component

import { Input } from "@projectdiscovery/pd-design-system";

<Input type="email" placeholder="Enter email" />
<Input type="password" placeholder="Password" disabled />

🎨 Design Tokens

This design system uses TypeScript-based design tokens with automatic CSS generation. All colors and semantic tokens are defined in TypeScript for type safety and maintainability.

Working with Tokens

# Generate CSS from TypeScript tokens
npm run generate-tokens

# Tokens are auto-generated before build
npm run build

Key files:

  • src/lib/tokens/primitives.ts - Color scales (100-950)
  • src/lib/tokens/semantic.ts - Semantic tokens (border, content, background)
  • src/styles/globals.css - Auto-generated CSS variables (don't edit directly!)

📖 Documentation:

Using Tokens

With Theme Object (Recommended for dynamic styling):

import { theme } from "@projectdiscovery/pd-design-system";

// Full TypeScript autocomplete!
<div
  style={{
    backgroundColor: theme.background.primary,
    color: theme.content.primary,
    border: `1px solid ${theme.border.blue}`,
  }}
/>;

// Access any token with autocomplete
const brandColor = theme.colors.blue[600]; // "#004BFF"

With Tailwind Classes (Recommended for static styling):

<div className="bg-background-primary text-content-primary border-border-blue" />

Direct Token Access:

import { blue, borderTokens } from "@projectdiscovery/pd-design-system";

const color = blue[500]; // "#3772FF"
const borderColor = borderTokens.light.primary;

🛠️ Development

Prerequisites

  • Node.js 18+
  • npm/yarn/pnpm

Setup

# Install dependencies
npm install

# Generate CSS tokens from TypeScript
npm run generate-tokens

# Start Storybook (component development & documentation)
npm run storybook

# Build the library (auto-generates tokens first)
npm run build

# Type check
npm run type-check

# Lint
npm run lint

📚 Storybook

Run Storybook to see all components with interactive examples:

npm run storybook

This will start Storybook at http://localhost:6006

🎨 Custom Storybook Theme

Our Storybook is styled with PD Design System! The entire Storybook UI uses:

  • Custom theme matching your design tokens
  • Welcome page built with PD components
  • Dark mode support
  • Branded documentation

See STORYBOOK.md for customization details.

🏗️ Project Structure

pd-ds/
├── src/
│   ├── components/
│   │   ├── Button/
│   │   │   ├── Button.tsx
│   │   │   ├── Button.stories.tsx
│   │   │   └── index.ts
│   │   ├── Card/
│   │   ├── Input/
│   │   └── ...
│   ├── lib/
│   │   ├── tokens/            # 🎨 TypeScript design tokens
│   │   │   ├── primitives.ts  # Color scales
│   │   │   ├── semantic.ts    # Semantic tokens
│   │   │   ├── generate-css.ts
│   │   │   ├── types.ts
│   │   │   └── index.ts
│   │   └── utils.ts           # Utility functions (cn, etc.)
│   ├── styles/
│   │   └── globals.css        # ⚠️ Auto-generated CSS variables
│   └── index.ts               # Main export file
├── scripts/
│   └── generate-css-tokens.ts # CSS generation script
├── .storybook/                # Storybook configuration
├── components.json            # shadcn/ui configuration
├── tailwind.config.js         # Tailwind configuration (uses TS tokens)
├── tsconfig.json              # TypeScript configuration
├── tsup.config.ts             # Build configuration
└── package.json

🎨 Adding shadcn/ui Components

To add more shadcn/ui components to this design system:

npx shadcn@latest add [component-name]

Example:

npx shadcn@latest add dialog
npx shadcn@latest add dropdown-menu
npx shadcn@latest add select

The components will be added to src/components/ and you can customize them as needed.

🌗 Dark Mode

The design system has built-in dark mode support. To enable dark mode in your app:

// Add the 'dark' class to your root element
<html className="dark">{/* Your app */}</html>

Or toggle it dynamically:

function ThemeToggle() {
  const [isDark, setIsDark] = useState(false);

  useEffect(() => {
    if (isDark) {
      document.documentElement.classList.add("dark");
    } else {
      document.documentElement.classList.remove("dark");
    }
  }, [isDark]);

  return <button onClick={() => setIsDark(!isDark)}>Toggle Theme</button>;
}

📝 Customization

Using the cn utility

All components use the cn utility for className merging:

import { Button, cn } from "@projectdiscovery/pd-design-system";

<Button className={cn("my-custom-class", someCondition && "conditional-class")}>
  Click me
</Button>;

Extending Components

You can extend components by wrapping them:

import { Button, type ButtonProps } from "@projectdiscovery/pd-design-system";

interface MyButtonProps extends ButtonProps {
  isLoading?: boolean;
}

export function MyButton({ isLoading, children, ...props }: MyButtonProps) {
  return (
    <Button {...props} disabled={isLoading || props.disabled}>
      {isLoading ? "Loading..." : children}
    </Button>
  );
}

📦 Publishing

To npm:

# 1. Build the library
npm run build

# 2. Update version
npm version patch|minor|major

# 3. Publish
npm publish

To private registry:

Update package.json:

{
  "publishConfig": {
    "registry": "https://your-private-registry.com"
  }
}

🤝 Contributing

  1. Add new components to src/components/[ComponentName]/
  2. Include TypeScript types
  3. Write Storybook stories
  4. Export from src/index.ts
  5. Update this README

📄 License

MIT

🔗 Links


Built with ❤️ using React, TypeScript, and Tailwind CSS