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

@avihq/ui

v0.2.30

Published

Avi's UI component library and design tokens — one theme for the site, the dashboard, and app panels.

Readme

@avihq/ui

Avi's UI component library and design tokens — one theme for the marketing site, the dashboard, and app panels.

Everything is styled through the design tokens in src/styles/tokens.css: semantic color groups (--color-background-*, --color-text-*, --color-border-*, --color-focus-ring-*), typography scales, radius, shadows. Light values live on :root, dark values on .dark — flipping the dark class on <html> re-themes every component.

Components

| Group | Components | |---|---| | Form controls | Button, Input, Textarea, Select, Checkbox, Switch, RadioGroup, Slider, TagInput, DatePicker, DateRangePicker, ToggleGroup | | Feedback | Alert, Badge, Menu, Modal (+ ModalHeader/ModalBody/ModalActions), Spinner | | Navigation | Tabs (compound: Tabs.Tab, Tabs.Panel; controlled or defaultValue) | | Data display | Card, Table (+ TableHeader/TableBody/TableRow/TableHead/TableCell), Heading, Text, Divider, CodeBlock (syntax-highlighted) | | Panel chrome | PanelShell, PanelBody, PanelHeader, Toolbar, EmptyState |

Components are styled with Tailwind utility classes over the tokens and carry no dependencies beyond the React peer — except CodeBlock, which ships real syntax highlighting via react-syntax-highlighter (PrismLight with a fixed grammar set, so only the registered languages land in your bundle).

Panel layout rule — never pad the panel's outer element. PanelHeader, Toolbar, Tabs, and tables draw edge-to-edge borders and carry their own internal padding; horizontal padding on an ancestor cuts those borders short of the panel edges. Use PanelShell as the unpadded full-height root with full-bleed rows directly inside it, and keep padding in PanelBody (its flush prop drops the padding for full-bleed tables/lists):

<PanelShell>
  <PanelHeader title="Customers" actions={<Button size="sm">Add</Button>} />
  <Toolbar>…</Toolbar>
  <PanelBody>…padded content…</PanelBody>
</PanelShell>

Tree-shaking: the dist is per-module and the package declares "sideEffects", so bundlers include only the components you import (plus the injected stylesheet on the /panel entry).

Optional modules

Heavier building blocks live behind their own entry points so the core stays lean — importing the root entry never pulls these in.

@avihq/ui/charts — themed Recharts v3 wrappers (LineChart, BarChart, AreaChart, PieChart, ScatterChart, RadarChart, ComposedChart, Tooltip) plus the Recharts primitives re-exported for composition:

import { LineChart, Line, XAxis, YAxis, Tooltip } from "@avihq/ui/charts";

<LineChart data={data} height={300}>
  <XAxis dataKey="month" />
  <YAxis />
  <Tooltip />
  <Line dataKey="revenue" />
</LineChart>

Panels get the chart CSS automatically (it's baked into the injected stylesheet). Tailwind surfaces add @import "@avihq/ui/styles/charts.css"; where they use charts.

@avihq/ui/data-table — virtualized DataTable on TanStack Table v8 + TanStack Virtual, with sorting, filtering, pagination, and row expansion (ColumnDef is re-exported for typing). Expansion composes from renderSubRow (return null to leave a row inert), expandIndicator (a leading chevron-node gutter with a dashed thread into the sub-row), isRowExpandable (rows can expand with no sub-row, purely to drive in-row rendering — cells read table.options.meta.isRowExpanded(row.id)), and rowClickable (per-row onRowClick gate). Presentation knobs: hideHeader (headerless, keeps column sizing), rowSeparator ("full" | "inset" | "none"), flush, compact:

import { DataTable } from "@avihq/ui/data-table";

<DataTable columns={[{ accessorKey: "name", header: "Name" }]} data={items} sortable virtualized />

@avihq/ui/editor — Avi's rich markdown editor (Milkdown): formatting toolbar, GFM, undo history, plain-text paste (Shift+Mod+V), mod+click link opening. Markdown strings in/out:

import { Editor } from "@avihq/ui/editor";

<Editor value={markdown} onChange={setMarkdown} placeholder="Write…" />

Panels get the editor CSS automatically; Tailwind surfaces add @import "@avihq/ui/styles/editor.css"; (and an @source for ui/src/editor so the toolbar's utility classes are generated).

Consuming

App panels (no CSS pipeline):

import { Button, Card } from "@avihq/ui/panel";

The /panel entry injects the precompiled stylesheet into the document on import — required inside Avi's sandboxed panel iframes, where CSS cannot be bundled separately.

Tailwind v4 surfaces (site, web):

@import "tailwindcss";
@import "@avihq/ui/styles/tokens.css";
@import "@avihq/ui/styles/theme.css";      /* Tailwind bridge: bg-bg-*, text-txt-*, border-bdr-*, ring-ring-*, heading-* */
@import "@avihq/ui/styles/reset.css";
@import "@avihq/ui/styles/components.css"; /* component CSS that utilities can't express */
@source "../../ui/src/components";         /* generate the utilities the components use */
import { Button } from "@avihq/ui";

theme.css resets Tailwind's default color palette — every color goes through a token. It also owns the dark custom variant; don't redeclare it.

The marketing site consumes the library like web does (components.css + @source): nav/CTA buttons, badges, and the docs renderers (CodeBlock, Table, Divider) are library components — Button as="a" covers the link CTAs — and the docs gallery (avi.run/docs/ui-components) renders the full library live. Only genuinely marketing-specific art (extrude cards, the animated dashboard mock, sheet/accordion) stays bespoke.

Anything else: import @avihq/ui/styles.css (the same precompiled sheet the panel entry injects).

Optional embedded font: the package ships Plus Jakarta Sans (variable 200–800, latin + latin-ext, ~100 KB, SIL OFL — see fonts/OFL.txt). Import @avihq/ui/styles/fonts.css to load it and switch --font-sans to it; leave it unimported to keep the system font stack. Bundled surfaces need a CSS pipeline that resolves url() assets; panels get the font automatically — the /panel entry's injected stylesheet carries the faces base64-inlined (~100 KB, since connect-src 'none' rules out fetching), and Avi's panel CSP allows font-src data:.

Styling by hand

Use the tokens directly — they are plain color values, never wrap them in hsl():

<div style={{ borderBottom: "1px solid var(--color-border-primary)", color: "var(--color-text-secondary)" }} />

Building

npm run build   # tsup (ESM + types) → @tailwindcss/cli (dist/styles.css) → emit-panel-styles.mjs (dist/panel-styles.js)

The library must build before the site/web/app builds that consume it (npm run build at the repo root orders this correctly).

Publishing

Automatic: bump version in package.json and merge to main — .github/workflows/publish-ui.yml publishes any version that isn't on the registry yet. Non-version changes to the package never trigger a publish.

Auth is npm trusted publishing (OIDC) — no token secret. One-time bootstrap: publish the first release manually (npm publish --access public from this directory), then register the workflow as a Trusted Publisher on npmjs.com (@avihq/ui → Settings → Trusted Publisher → GitHub Actions: avi-hq / avi / publish-ui.yml).

Provenance

The core components, charts, and data-table were ported from Creature's open-mcp sdk-ui (MIT, Serverless Inc.) and re-tokened onto Avi's design system. The editor, Modal, and the compound Table/Tabs extensions are Avi originals.