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

@shreyajirwankar/dashboard

v1.0.1

Published

Reusable, framework-agnostic React dashboard UI kit — layout shell, navigation, theming and data components for any React + TypeScript application.

Readme

@vrize/dashboard

A reusable, framework-agnostic React dashboard UI kit — layout shell, navigation, theming, and data-display components for any React + TypeScript web app.

The package ships only presentation and layout primitives. It owns no routes, no data fetching, and no business logic — every consuming project supplies its own logo, name, theme, navigation, routes, pages, and data.

Build dashboard once
       ↓
Publish @vrize/dashboard
       ↓
────────────────────────────
↓             ↓            ↓
Project A   Project B    Project C
↓             ↓            ↓
import       import        import
package      package       package

Install

pnpm add @vrize/dashboard react react-dom

react and react-dom are peer dependencies (>=18) — the package never bundles its own copy of React, so it shares the host app's instance and stays small.

Quick start

1. Import the stylesheet once, near your app's own global CSS:

// main.tsx
import '@vrize/dashboard/styles.css';

2. Describe your dashboard — brand, navigation, theme, and how links should render — in one plain object:

// dashboard.config.tsx
import type { DashboardConfig, NavigationItem } from '@vrize/dashboard';
import { Link, useLocation } from 'react-router-dom';
import { HomeIcon, OrdersIcon, SettingsIcon } from './icons'; // your own icons
import logo from './assets/logo.svg';

export const navigation: NavigationItem[] = [
  { id: 'home', label: 'Home', href: '/', icon: <HomeIcon /> },
  {
    id: 'orders',
    label: 'Orders',
    href: '/orders',
    icon: <OrdersIcon />,
    badge: '12',
  },
  {
    id: 'settings',
    label: 'Settings',
    icon: <SettingsIcon />,
    children: [
      { id: 'settings-profile', label: 'Profile', href: '/settings/profile' },
      { id: 'settings-billing', label: 'Billing', href: '/settings/billing' },
    ],
  },
];

export function useDashboardConfig(): DashboardConfig {
  const location = useLocation();

  return {
    brand: {
      name: 'Acme Inc.',
      logo: <img src={logo} alt="" />,
      href: '/',
    },
    navigation,
    activePath: location.pathname,
    theme: {
      mode: 'system',
      colors: { primary: '#4f46e5' },
      radius: '10px',
    },
    // The package never imports a router — you decide how links render.
    renderLink: ({ href, children, className, active, onClick }) => (
      <Link to={href} className={className} onClick={onClick} aria-current={active ? 'page' : undefined}>
        {children}
      </Link>
    ),
  };
}

3. Wrap your routed content in AppShell:

// App.tsx
import { AppShell } from '@vrize/dashboard';
import { Routes, Route } from 'react-router-dom';
import { useDashboardConfig } from './dashboard.config';
import OrdersPage from './pages/OrdersPage';
import HomePage from './pages/HomePage';

export default function App() {
  const config = useDashboardConfig();

  return (
    <AppShell config={config}>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/orders" element={<OrdersPage />} />
      </Routes>
    </AppShell>
  );
}

That's it — sidebar, header, active-link highlighting, mobile drawer, and light/dark theming all come from the package. Your project owns every route, page component, and piece of business logic.

Building a page with the components

import {
  PageHeader,
  StatCard,
  Card,
  DataTable,
  Pagination,
  Button,
  usePagination,
  type ColumnDef,
} from '@vrize/dashboard';

interface Order {
  id: string;
  customer: string;
  total: number;
  status: 'paid' | 'pending';
}

const columns: ColumnDef<Order>[] = [
  { id: 'id', header: 'Order', accessor: 'id', sortable: true },
  { id: 'customer', header: 'Customer', accessor: 'customer', sortable: true },
  {
    id: 'total',
    header: 'Total',
    accessor: (row) => `$${row.total.toFixed(2)}`,
    align: 'right',
    sortable: true,
  },
];

export default function OrdersPage() {
  const orders = useOrders(); // your own data hook — the package has no opinion here
  const pagination = usePagination({ total: orders.length, initialPageSize: 10 });

  return (
    <>
      <PageHeader
        title="Orders"
        description="All orders across every channel."
        breadcrumbs={[{ label: 'Home', href: '/' }, { label: 'Orders' }]}
        actions={<Button variant="primary">New order</Button>}
      />

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16 }}>
        <StatCard label="Revenue" value="$12,400" delta="+4.3%" trend="up" />
        <StatCard label="Open orders" value={orders.length} />
        <StatCard label="Refund rate" value="1.2%" trend="down" invertTrendColor />
      </div>

      <Card title="Recent orders">
        <DataTable columns={columns} data={pagination.slice(orders)} getRowId={(row) => row.id} />
        <Pagination
          page={pagination.page}
          pageCount={pagination.pageCount}
          total={orders.length}
          pageSize={pagination.pageSize}
          onPageChange={pagination.setPage}
          onPageSizeChange={pagination.setPageSize}
        />
      </Card>
    </>
  );
}

What each project supplies vs. what the package supplies

| Supplied by your project | Supplied by the package | | --- | --- | | Logo, company name, tagline | AppShell layout (sidebar + header + content) | | Navigation items and routes | Sidebar / Header chrome, mobile drawer, collapse | | Theme colors, radius, density | Theming engine (CSS variables, light/dark) | | Router (react-router, Next, TanStack…) | renderLink bridge — no router dependency | | Pages, data fetching, business logic | Card, StatCard, DataTable, Modal, Dropdown, Tabs, Button, Input, Breadcrumbs, PageHeader, Pagination, Badge, Avatar, EmptyState |

The package is framework-agnostic below the React layer: it has no dependency on any router, state manager, or data-fetching library, so it drops into a Next.js app, a Vite SPA, or a Remix app equally well.

Exports

Layout

AppShell, Sidebar, SidebarToggle, Header,
DashboardProvider, useDashboard, useDashboardOptional

Components

Card, StatCard, DataTable, Pagination, Modal, Dropdown, Tabs,
Button, Input, Breadcrumbs, PageHeader,
Badge, Avatar, EmptyState, Skeleton, Spinner, ThemeToggle

Navigation

NavLink, flattenNavigation, findNavigationTrail, isBranchActive, isSection,
defaultIsItemActive

Theme

ThemeProvider, useTheme, useThemeOptional, useScopeProps,
createThemeVars, themeVarsToCss, lightColors, darkColors, defaultTheme

Hooks

useDisclosure, usePagination, useMediaQuery, useClickOutside, useLocalStorage

Types

DashboardConfig, NavigationItem, NavigationSection, NavigationConfig,
ThemeConfig, ThemeColors, ThemeMode, ResolvedThemeMode,
BrandConfig, SidebarBehaviour, LinkRenderer, LinkRenderProps,
Size, Tone, Align, SortDirection, SortState

Theming

Every color, radius, spacing, and font is a CSS custom property written by ThemeProvider (mounted for you by AppShell). Pass a ThemeConfig — no class overrides or CSS-in-JS wiring required:

const theme: ThemeConfig = {
  mode: 'system',                 // 'light' | 'dark' | 'system'
  colors: { primary: '#16a34a' }, // light-mode overrides
  darkColors: { primary: '#4ade80' }, // dark-mode-only overrides
  radius: '6px',
  density: 'compact',             // 'comfortable' | 'compact'
  sidebarWidth: '280px',
  cssVars: { '--dsh-shadow-md': '0 8px 24px rgba(0,0,0,.12)' }, // escape hatch
};

Portalled UI (Modal, Dropdown) automatically inherits the same theme scope even though it renders into document.body.

Routing

The package never imports a router. Every internal link is rendered through your renderLink function (DashboardConfig.renderLink), so it works unchanged with React Router, Next.js <Link>, TanStack Router, or a plain <a> (the default if you omit it).

Icons

The package ships no icon library dependency. Pass any ReactNode — an <svg>, a lucide-react icon, an emoji — to NavigationItem.icon, Button.leftIcon, StatCard.icon, and similar props. A small internal icon set covers only the chrome the components own (chevrons, close button, sort arrows).

Development

pnpm install
pnpm dev          # watch build, unminified
pnpm build        # typecheck + production build → dist/
pnpm typecheck    # tsc --noEmit only

Build output:

dist/
├── index.js       ESM bundle
├── index.cjs      CommonJS bundle
├── index.d.ts     rolled-up type declarations
└── styles.css     stylesheet (import explicitly — never auto-injected)

Publishing

pnpm build
pnpm publish --access restricted   # or your org's registry flow

prepublishOnly re-builds automatically, so dist/ is always fresh at publish time. Only dist/, README.md, and LICENSE ship in the published tarball — no demo app, no source .tsx, no dev tooling.