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

@legoblock/ui

v0.0.4

Published

A headless React library for managing nested tree structures with immutable updates.

Readme

@legoblock/ui

A headless React library for rendering and managing nested tree structures with immutable updates. Perfect for building file explorers, nested menus, organizational charts, and any hierarchical data visualization.

Live Documentation & Examples: https://legoblocks.ayushpapnai.in/

Features

  • 🌳 Headless Design: Complete control over UI/UX while the library handles recursion and state management
  • 🔄 Immutable Updates: All operations return new tree instances, perfect for React state management
  • Performance Optimized: Path-based targeting and single clone operations for efficient updates
  • 🎯 Flexible Data Structure: Works with any tree data shape, not locked into specific schemas
  • 🛠️ Rich Operations: Add, delete, update nodes with support for complex operations like bulk updates
  • 📍 Path-based Navigation: Each node knows its exact location in the tree for precise operations
  • 🔧 TypeScript Support: Full type safety with comprehensive interfaces

Installation

npm install @legoblock/ui
# or
yarn add @legoblock/ui
# or
pnpm add @legoblock/ui

Quick Start

import { NestedStructure, RecurringNodeProps } from '@legoblock/ui';
import { useState } from 'react';

type Node = {
  name: string;
  type: 'file' | 'folder';
  children?: Node[];
};

function FileNode({ node, children, addNode, deleteNode }: RecurringNodeProps<Node>) {
  return (
    <div>
      <span>{node?.name}</span>
      {node?.type === 'folder' && <button onClick={() => addNode && addNode({ name: 'new-file.ts', type: 'file' })}>+</button>}
      <button onClick={deleteNode}>Delete</button>
      {children}
    </div>
  );
}

export default function App() {
  const [tree, setTree] = useState<Node[]>([{ name: 'src', type: 'folder', children: [{ name: 'index.ts', type: 'file' }] }]);

  return <NestedStructure recurringNode={<FileNode />} recurringData={tree} updatedRecurringData={setTree} />;
}

Core Concepts

Headless Rendering

You provide a React component that defines how each node should look and behave. The library handles the recursion and state management, cloning your component at each tree level.

Immutable Updates

All operations (add, delete, update) work on cloned data structures, ensuring your React state remains predictable and your components re-render efficiently.

Path-based Operations

Each node receives an accessPath (array of indices) that describes its exact location in the tree, enabling precise operations without searching the entire tree.

API Reference

<NestedStructure />

The main component that renders your tree structure.

Props:

  • recurringNode: ReactElement<RecurringNodeProps<T>> - Your component that will be rendered for each node
  • recurringData: any[] - Root array of nodes (each can have optional children array)
  • updatedRecurringData?: (updatedData: any[]) => void - Callback fired when tree is modified

RecurringNodeProps<T>

Props injected into your component at each node:

interface RecurringNodeProps<T> {
  node?: T; // Current node data
  children?: React.ReactNode; // Rendered subtree
  accessPath?: number[]; // Path to this node [0, 2, 1]
  deleteNode?: () => void; // Delete this node
  addNode?: (newNode: T, position?: 'child' | 'before' | 'after') => void;
  updateNode?: (updatedNode: T) => void;
  updateAllChildrenNode?: (
    payload: Partial<T> | ((node: T) => T),
    options?: {
      includeSelf?: boolean; // Include current node (default: true)
      depth?: number; // Max depth to update (default: Infinity)
      predicate?: (node: T) => boolean; // Only update matching nodes
      childrenField?: keyof T & string; // Custom children field (default: 'children')
    }
  ) => void;
}

Use Cases

1. File Explorer

Perfect for building file system browsers, code editors, or project explorers.

2. Nested Filters with Cascade Selection

Build filter systems where selecting a parent automatically selects all children, or use updateAllChildrenNode to bulk update entire subtrees.

3. Organizational Charts

Build company hierarchies, family trees, or any organizational structure.

4. Nested Menus

Create multi-level navigation menus with dynamic content.

5. Comment Threads

Render nested comment structures with reply functionality.

Advanced Features

  • Bulk Operations: Use updateAllChildrenNode to update entire subtrees with predicates and depth limits
  • Custom Children Field: Specify custom field names for children (default: 'children')
  • Path-based Operations: Each node knows its exact location via accessPath
  • Position-aware Adding: Insert nodes as children, before, or after current node

Performance Considerations

  • Path-based targeting: Operations are O(depth) rather than O(tree size)
  • Single clone per operation: Only one structuredClone per update
  • Localized updates: Only affected subtrees are modified
  • Stable references: Unchanged parts maintain referential equality

TypeScript Support

The library is fully typed with comprehensive interfaces. Your node types will be properly inferred throughout your component tree, providing full type safety for all operations.

License

MIT © Ayush Papnai

Contributing

Issues and pull requests are welcome! Please check the documentation in the /apps/docs directory for more examples and detailed usage patterns.