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

rstree-ui

v0.1.8

Published

A modern React tree component library with virtualization, search, and Tailwind CSS support. Features include multi-select, checkboxes, custom icons, fuzzy search with highlighting, and virtual scrolling for large datasets.

Readme

RsTree

npm version Build Status TypeScript MIT License

A Morden React tree component library with virtualization, search, and Tailwind CSS support. Demo

Another choice for React tree components. Tree component screenshot

Features

  • Virtual scrolling for large datasets (1000+ nodes)
  • Fuzzy search with highlighting and auto-expansion
  • Full customization of icons and nodes
  • Responsive design for all screen sizes
  • TypeScript support with complete type definitions
  • Multiple selection modes - single/multi-select, checkboxes, disabled states
  • Tailwind CSS integration - works with or without Tailwind
  • Tree utilities - connecting lines, click-to-toggle, auto-expand

Installation

npm install rstree-ui

Peer Dependencies

npm install react react-dom

Tailwind CSS Support (Optional)

Works with Tailwind CSS v3+ and v4+, or as a standalone component.

Quick Start

Option 1: With Tailwind CSS v4

Add to your CSS file:

@import "tailwindcss";
@source "../node_modules/rstree-ui";

Option 2: With Tailwind CSS v3

Add the library path to your tailwind.config.js:

module.exports = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx}",
    "./node_modules/rstree-ui/**/*.{js,ts,jsx,tsx}",
  ],
  // ... other config
}

Option 3: Standalone CSS

Import the pre-compiled styles:

import 'rstree-ui/style.css'

Basic Usage

import { RsTree } from 'rstree-ui'

const data = [
  {
    id: '1',
    label: 'Documents',
    children: [
      { id: '1-1', label: 'Resume.pdf' },
      { id: '1-2', label: 'Cover Letter.docx' }
    ]
  },
  { id: '2', label: 'Pictures' }
]

function App() {
  const [selectedIds, setSelectedIds] = useState([])
  
  return (
    <RsTree 
      data={data}
      selectedIds={selectedIds}
      onSelect={setSelectedIds}
      showIcons={true}
    />
  )
}

API Reference

RsTree Props

Core Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | data | TreeNode[] | required | Tree data structure | | selectedIds | string[] | [] | Array of selected node IDs | | onSelect | (ids: string[]) => void | - | Selection change callback | | multiSelect | boolean | false | Enable multi-selection |

Expansion Control

| Prop | Type | Default | Description | |------|------|---------|-------------| | expandedIds | string[] | [] | Array of expanded node IDs | | onExpand | (ids: string[]) => void | - | Expansion change callback | | clickToToggle | boolean | false | Click anywhere on node to toggle |

Checkbox Support

| Prop | Type | Default | Description | |------|------|---------|-------------| | checkable | boolean | false | Enable checkboxes | | checkedIds | string[] | [] | Array of checked node IDs | | onCheck | (ids: string[]) => void | - | Check state change callback |

Visual Customization

| Prop | Type | Default | Description | |------|------|---------|-------------| | showIcons | boolean | true | Show folder/file icons | | showTreeLines | boolean | false | Show connecting lines | | disabled | boolean | false | Disable all interactions | | className | string | '' | Additional CSS classes for container | | treeLineClassName | string | '' | Custom CSS classes for tree lines | | treeNodeClassName | string | '' | Custom CSS classes for tree nodes |

Custom Icons

| Prop | Type | Default | Description | |------|------|---------|-------------| | expandIcon | React.ReactNode | <ChevronRight /> | Custom expand icon | | collapseIcon | React.ReactNode | <ChevronDown /> | Custom collapse icon | | folderIcon | React.ReactNode | <Folder /> | Custom folder icon | | fileIcon | React.ReactNode | <File /> | Custom file icon |

Search Features

| Prop | Type | Default | Description | |------|------|---------|-------------| | searchTerm | string | '' | Search query string | | autoExpandSearch | boolean | true | Auto-expand search results | | onSearchMatch | (id: string \| null) => void | - | Best match callback |

Performance & Layout

| Prop | Type | Default | Description | |------|------|---------|-------------| | virtualizeEnabled | boolean | true | Enable virtual scrolling | | height | number | 400 | Fixed height in pixels | | itemHeight | number | 32 | Height per item | | autoHeight | boolean | false | Auto-adjust height | | maxHeight | number | 400 | Maximum height | | minHeight | number | 100 | Minimum height |

Advanced Customization

| Prop | Type | Description | |------|------|-------------| | renderNode | (node: TreeNode, props: TreeNodeRenderProps) => React.ReactNode | Custom node renderer | | onNodeClick | (node: TreeNode, event: React.MouseEvent) => void | Node click handler |

TreeNode Interface

interface TreeNode {
  id: string              // Unique identifier
  label: string           // Display text
  children?: TreeNode[]   // Child nodes
  disabled?: boolean      // Disable this node
  icon?: React.ComponentType<{ className?: string }> | ReactNode  // Custom icon for this node
  metadata?: Record<string, unknown>  // Additional metadata
  data?: any             // Additional custom data
}

Examples

Multi-Select Tree

<RsTree
  data={data}
  multiSelect={true}
  selectedIds={selectedIds}
  onSelect={setSelectedIds}
/>

Checkable Tree

<RsTree
  data={data}
  checkable={true}
  checkedIds={checkedIds}
  onCheck={setCheckedIds}
/>

Search with Auto-Expand

<RsTree
  data={data}
  searchTerm={searchTerm}
  autoExpandSearch={true}
  virtualizeEnabled={true}
/>

Custom Icons

const MyExpandIcon = <span>▶</span>
const MyCollapseIcon = <span>▼</span>

<RsTree
  data={data}
  expandIcon={MyExpandIcon}
  collapseIcon={MyCollapseIcon}
  showIcons={true}
/>

Large Dataset with Virtualization

<RsTree
  data={largeDataset}
  height={500}
  virtualizeEnabled={true}
  itemHeight={36}
/>

Custom Styling

// Custom tree lines and node styling
<RsTree
  data={data}
  showTreeLines={true}
  treeLineClassName="border-blue-300 border-dashed"
  treeNodeClassName="rounded-lg shadow-sm hover:shadow-md"
  className="border border-gray-200 rounded-md"
/>

// Dark theme styling example
<RsTree
  data={data}
  showTreeLines={true}
  treeLineClassName="border-gray-600"
  treeNodeClassName="text-gray-100 hover:bg-gray-800 bg-gray-900"
  className="bg-gray-900 border border-gray-700"
/>

Custom Node Renderer

The library automatically handles layout structure (indentation, tree lines, expand icons, checkboxes) while allowing you to customize the content area:

// Rich project management tree with custom metadata
const projectData = [
  {
    id: "project-1",
    label: "React Dashboard",
    data: { 
      type: "project", 
      status: "active", 
      priority: "high", 
      lastModified: "2 hours ago" 
    },
    children: [
      { 
        id: "src", 
        label: "src", 
        data: { type: "folder", fileCount: 12, size: "298 KB" }
      },
      { 
        id: "app.tsx", 
        label: "App.tsx", 
        data: { type: "file", language: "typescript", size: "12.5 KB", lines: 340 }
      },
    ]
  }
];

const customRenderer = (node, props) => {
  const { data } = node;
  
  if (data?.type === "project") {
    return (
      <div className="flex items-center gap-3 py-1 w-full min-w-0">
        <div className="flex items-center gap-2 flex-1 min-w-0">
          <span className="font-semibold text-gray-100">{node.label}</span>
          <span className={`px-2 py-0.5 text-xs rounded-full ${
            data.status === 'active' ? 'bg-green-500/20 text-green-400' : 'bg-blue-500/20 text-blue-400'
          }`}>
            {data.status}
          </span>
          <div className="w-2 h-2 rounded-full bg-red-500"></div>
          <span className="text-xs text-gray-400">{data.priority}</span>
        </div>
        <span className="text-xs text-gray-400">📅 {data.lastModified}</span>
      </div>
    );
  }
  
  if (data?.type === "file") {
    return (
      <div className="flex items-center gap-3 py-1 w-full min-w-0">
        <div className="flex items-center gap-2 flex-1 min-w-0">
          <span className="w-6 h-6 bg-gray-700 text-gray-300 rounded text-xs flex items-center justify-center font-mono">
            {data.language === 'typescript' ? 'TS' : 'JS'}
          </span>
          <span className="text-gray-200">{node.label}</span>
        </div>
        <div className="flex items-center gap-3 text-xs text-gray-500">
          <span>{data.lines} lines</span>
          <span>{data.size}</span>
        </div>
      </div>
    );
  }
  
  return <span>{node.label}</span>;
};

<RsTree
  data={projectData}
  renderNode={customRenderer}
  showTreeLines={true}
  multiSelect={true}
/>

Key Features:

  • Automatic Layout: Indentation, tree lines, and controls are handled automatically
  • Rich Content: Display badges, icons, metadata, and custom styling
  • Responsive Design: Content adapts to available space with proper text truncation
  • Interaction Support: Maintain full tree functionality (select, expand, check)

Note: Your custom content is automatically wrapped in the standard tree layout structure, so you don't need to handle indentation, tree lines, or control elements yourself. Just focus on the node content.

Development

Install Dependencies

npm install

Development

npm run dev    # Watch mode
npm run build  # Build library
npm run test   # Run tests
npm run lint   # Lint code

Build

npm run build

Testing

npm run test

Contributing

Contributions are welcome!

  1. Fork the repository
  2. Create your feature branch
  3. Commit your changes
  4. Push to the branch
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support