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

@ahrowe/ui

v0.41.2

Published

A React UI component library with theming, CSS Modules, and TypeScript support

Readme

ahrowe-ui

A React UI component library with theming, form validation, and a full component suite.

Browse the components, with live props and a theme editor.

Install

npm install @ahrowe/ui

Usage

import '@ahrowe/ui/style.css';
import { AhroweProvider } from '@ahrowe/ui';

function Root() {
  return (
    <AhroweProvider>
      <App />
    </AhroweProvider>
  );
}

AhroweProvider is required, once, at the root. It injects the CSS variables the components paint with, so without it they render unstyled. It also renders the element Modal, Tooltip, Popover, Toast and Menu portal into, and shows toasts. Two themes ship, defaultTheme (dark) and lightTheme. Pass your own to themes to replace them. See docs/AhroweProvider.md.

Before you install

Things that might rule the package out.

  • React 19 or newer. Refs are plain props here, no forwardRef, and that only works from 19 on.
  • Modern browsers. Chrome and Edge 111, Firefox 114, Safari 16.4. Nothing is transpiled below that and no polyfill ships. Two details want a newer Firefox: ScrollFade's edge fade eases from 128 and snaps before it, and OptionPicker rings the whole group from 121. Both still work either way. CI only runs Chromium.
  • One stylesheet. @ahrowe/ui/style.css is 138 KB, 26 KB gzipped, and covers everything. There is no per-component CSS. It sits in @layer ahrowe-ui, so your own unlayered CSS wins no matter which loads first.
  • No right to left. The stylesheets use margin-left and friends rather than logical properties, so nothing mirrors.
  • 0.x. A minor can break something, a patch does not. The changelog is written by hand and says what to change. 1.0 waits until the API stops moving, so pin the minor if that matters to you.
  • Server components. Every module is 'use client'. Nothing renders on the server, but you can import it into an RSC app without a wrapper.

Accessibility

Native elements where they exist, ARIA roles and state where they do not. Everything works from the keyboard. Groups that act as one control (RadioGroup, OptionPicker, Menu, Tree) take a single tab stop and move with the arrow keys, and :focus-visible keeps a ring off mouse clicks.

Modal traps focus, closes on Escape and hands focus back. Popover does not trap, on purpose, but Escape still returns you to the trigger. Stack overlays and only the top one hears Escape.

Animation respects prefers-reduced-motion. The loading spinners and Toast's countdown bar keep moving, because a frozen one would be lying.

None of this is audited. No axe run in CI, no screen reader matrix, and contrast comes from the theme you pass rather than from the library.

Claude Code

The docs ship inside the package and Claude reads them out of node_modules. Three ways in.

The plugin installs a skill and the MCP server together. The skill costs one line of context until Claude actually works on UI.

/plugin marketplace add AndreasWeinzierl/ahrowe-ui
/plugin install ahrowe-ui@ahrowe

For a whole team at once, commit this to the project's .claude/settings.json instead:

{
  "extraKnownMarketplaces": {
    "ahrowe": { "source": { "source": "github", "repo": "AndreasWeinzierl/ahrowe-ui" } }
  },
  "enabledPlugins": [{ "name": "ahrowe-ui", "marketplace": "ahrowe" }]
}

The docs index is one line in your own CLAUDE.md:

@node_modules/@ahrowe/ui/docs/CLAUDE.md

It holds the rules common to every component and a table pointing at docs/<Name>.md, which Claude opens when it needs one. This one loads in every session, where the plugin's skill only wakes up for UI work.

The MCP server on its own:

claude mcp add --transport stdio ahrowe-ui --scope project -- npx --no ahrowe-ui-mcp

search_components finds a component from a description, get_component_docs returns one doc and list_components lists them all. Each doc is a resource too, so you can drop one in yourself with @ahrowe-ui:ahrowe-ui://docs/Button. The ahrowe-ui-mcp bin comes with the package, so it only runs where @ahrowe/ui is installed.

Components

| Component | Description | |-----------|-------------| | Accordion | Collapsible sections for progressive disclosure — FAQs, settings panels, long-form content that users expand on demand | | ActionButtons | Standardised Submit / Cancel button pair for forms, dialogs, and drawer footers | | ActionIcon | Clickable icon button without a label — toolbar actions, table row actions, icon-only controls | | AhroweProvider | The one wrapper an app needs, at its root: it applies the theme, sets default props for every component, shows toasts and renders the element that Modal, Tooltip, Popover, Menu and Toast portal into | | Alert, AlertStyleType | A persistent inline status message, used for form-level errors, page/section banners, empty-config warnings, and "here's what changed" notices | | AnimatedLogo | A self-drawing SVG mark for splash/loading screens, empty states, or anywhere a brand or icon mark should feel alive rather than static | | AnimatedText, AnimatedTextVariant, AnimatedTextUnit | Decorative text entrance or emphasis effect, for hero headlines, empty-state messages, "premium"/"new" callouts, loading/decoding states | | Avatar, AvatarGroup | User or entity image — profile pictures, comment authors, member lists | | Badge, BadgeStyleType, BadgePosition | Small count or status indicator — unread counts, notification dots, "new" markers | | BodyEnd | Renders children through a React portal, to the end of the app | | Breadcrumb | A trail showing the current page's position within a hierarchy, with links back to each ancestor, such as a file browser path, a category/subcategory drill-down, or a multi-level settings page | | Button, ButtonStyleType, ButtonSize, ButtonType | Primary interactive action trigger | | ButtonGroup, ButtonGroupOrientation | Joins a row (or column) of buttons into a single seamless control, merging their borders and rounding only the outer corners | | Calendar, CalendarView | Showing and editing your own events over time, in month, week, day and agenda views: bookings, shifts, appointments, a team schedule | | Card, CardStyleType, CardHeader, CardMedia, CardContent, CardActions | Surface container for grouping related content — list items, profile cards, dashboard tiles, product listings | | Carousel | A slide track for stepping through a set of items one at a time, with arrows, dots, and drag/swipe support, plus optional autoplay | | Checkbox | Boolean toggle input — settings, multi-select lists, accept terms, feature flags | | Chip, ChipContainer, ChipStyleType | Compact tag, label, or filter token — selected items, applied filters, category badges, user avatars with remove | | ColorPicker | Hex colour selection — theme editors, annotation tools, customisation panels | | CommandPalette | A search-first dialog for running any command or jumping anywhere in the app from the keyboard, usually opened with ⌘K / Ctrl+K | | ConfigProvider | Set global default props for library components once, near the root of your app, instead of repeating the same prop on every instance | | ConfirmModal | Confirmation dialog before destructive or irreversible actions — delete, archive, send, overwrite | | CopyButton | Icon-only button that copies a value to the clipboard: an invoice number, an ID in a table row, an API key or share link inside an Input | | DatePicker, dateToDay, dayToDate, dateToTime, dayTimeToDate | Date selection input — booking forms, birth date fields, date range pickers, deadline selectors | | Divider, DividerTextPosition, DividerOrientation | A rule that separates sections of content — horizontal by default, filling the width of its parent | | Drawer | Inline horizontal panel that collapses and expands by animating its width — side panels, navigation rails, detail/filter panes that slide open beside the main content | | DropZone, DropZoneReturnType, DropZoneStatus | Drag-and-drop file upload area, optionally click-to-open the native picker | | Dropdown | Single-value selection from a list — country pickers, status selectors, category filters, any select-style input | | EmptyState | Placeholder shown when a list, table, or search result has no items — empty inboxes, no search matches, freshly-created sections | | ErrorBoundary | Wrap any subtree whose render errors shouldn't take down the rest of the app — a widget, a route, a third-party embed, a list row | | Fab | Floating action button — primary screen action (create, add, compose), optionally with a speed-dial sub-menu | | Flip | Flip a front/back pair of content 180°, like a physical playing card | | emptyFloorPlan, addWall, derivePlan | The shared data model behind RoomDrawer and RoomViewer | | FormValidator, Validators, useFormValidator | Track and validate a single form field's value, dirty/touched state, and errors | | useFormValidatorGroup, FormValidatorGroup, FormValidator, Validators | Manage a whole form — multiple fields, a single submit handler, validate-on-submit, dirty/touched tracking across the form, and mapping server-side errors back onto the right fields | | useHotkeys, formatHotkey, useMediaQuery, useCoarsePointer, useVisualViewportSize, useScrollEdges, useSwipeDismiss, useOverlay, useClipboard, tabbablesIn | Standalone React hooks the library uses internally and publishes for the same jobs in your own code: keyboard shortcuts, media queries, the mobile keyboard's viewport, scroll-edge detection, swipe-to-dismiss, copying to the clipboard, and the Escape / focus-trap / scroll-lock behaviour behind a custom overlay | | IconPicker | Pick one item from a visual icon/image grid — category selectors, emoji-style pickers, avatar selectors, anything where each option is best represented by an icon or image rather than text alone | | IdleManager | Show something only once the user has stopped interacting — a screen saver, a session-timeout warning, an "are you still there?" prompt, an idle dashboard view | | Input, InputType | Text input with floating label, validation state, and type variants | | InputDropdown | Combobox-style input — the user can type to filter and also pick from a dropdown list | | InteractableDiv | Accessible <div> that behaves like a button — click and keyboard (Enter/Space) events, with proper ARIA semantics | | KanbanBoard, KanbanColumn | Drag-and-drop board with columns — task management, workflow stages, status boards (e.g. Todo / In Progress / Done) | | KlipyPicker | GIF picker backed by the Klipy API — chat reactions, message composers, content authoring tools | | SpinnerLoading | A loading indicator for async operations: page loads, data fetching, or covering a region while it refreshes | | Menu, menuHotkeys | A list of actions hanging off a trigger — a row's "more" button, a toolbar overflow, a context menu on a card | | Modal | Full overlay dialog — forms, detail views, confirmations, wizards that need to block the rest of the UI | | MultiSelect | Pick several options from a list | | NumberInput | Numeric input with formatting — prices, quantities, percentages, phone numbers with separators | | OptionPicker | Segmented control for picking exactly one option from a small set — view modes, sort directions, simple tab-like switches | | OtpInput, OtpInputCharset | A one-time-passcode / verification-code input, rendered as one box per character | | Overscroll | Mobile-style collapsing header that shrinks as the user scrolls — profile pages, detail screens, anywhere a large hero area should yield space to content on scroll | | Pagination | Move through server-paged results a page at a time — a results list, an admin table, a report | | Popover | Any panel anchored to a trigger: profile cards, quick forms, action menus, pickers, filter dropdowns | | ProgressBar | Visual progress indicator — file uploads, multi-step completion, storage usage, stacked stats (e.g. budget breakdown) | | RadioGroup, RadioGroupOrientation | Single-choice selection from a small, always-visible set of options — plan pickers, shipping methods, yes/no/maybe, settings with 2–5 mutually exclusive choices | | Rating | A star rating input or display, for review scores, feedback prompts, and quality indicators | | RevealLens | A two-layer reveal/magnifier effect — an overlay covers a background by default, and moving the pointer over the component uncovers the background in an area around the cursor | | Ripple | Material-style ink ripple effect on any interactive element — buttons, list items, cards, tiles | | RoomDrawer | An interactive floor plan editor | | RoomViewer | Shows a floor plan someone can look at and click, without letting them change it — a building directory, a booking screen, a dashboard beside a room list | | ScrollFade, ScrollFadeAxis | A scrollable box whose content dissolves at the edge it is scrolling past, instead of being cut off mid-line against it | | ScrollbarProvider | Applies custom scrollbar styling to a scrollable region — use to keep scrollbar appearance consistent with the theme | | SearchInput | Search field with built-in debouncing and an optional result count line — list filters, search-as-you-type pages | | SectionHeader, SectionHeaderSize | A reusable heading block for the top of a page, panel, card, or any section — a title with an optional subtitle, a leading icon or thumbnail, and a trailing actions area | | Skeleton, SkeletonVariant, SkeletonAnimation | Content-shaped loading placeholder, shown while real content is being fetched — more polished than a spinner for content-heavy pages (lists, cards, profile headers) | | Slider | Let the user pick a number from a continuous or stepped range by dragging a thumb: volume, brightness, price ranges, zoom, quality presets | | SplitButton | A primary action button with a small attached dropdown for closely related secondary actions, e.g. "Save ▾" opening "Save as draft" / "Save and close" | | Stepper | Step progress indicator for multi-step forms, onboarding flows, and checkout wizards | | Sticky | Pin a piece of content to the top of the viewport once the page scrolls past it — section headers, toolbars, filter bars, table headers | | Switch | Sliding boolean toggle — settings panels, feature flags, preference lists | | TabHeader | A horizontal row of tabs to switch between sibling views or sections — settings panels, dashboards, detail pages | | Textarea | Multiline text input — comments, descriptions, notes, code snippets, long-form content | | ThemeProvider | Applies a theme to its subtree, injecting its CSS custom properties as inline styles so every component inside can use them | | Tilt, TiltGroup | Wrap content that should tilt toward the cursor in 3D | | TimeInput | Time-of-day selection — appointment times, opening hours, shift starts, reminders | | Timeline, TimelineAlignment, TimelineItemStatus | A vertical list of dated events, connected by a line, for audit logs, activity feeds, order status history, and deploy logs | | Timer | A countdown timer with a depleting ring, add/remove-time and pause/cancel controls, and an imperative ref API | | showToast | Non-blocking notifications — save confirmations, error alerts, info messages, warnings | | Tooltip | Contextual help, info icons, field explanations, error pointers | | Tree, flattenTree | A hierarchical list the user can expand, collapse and pick from: categories, nested locations, folder structures, org charts | | VirtualList | Efficiently render large lists or tables — thousands of rows rendered with a virtualised scroll window so only visible rows are in the DOM | | WeatherIcon, WeatherType | An animated weather symbol for a forecast, a dashboard widget or a day selector, one per condition a forecast reports | | Wizard | Animated step container for multi-step forms and flows |

Services

Localisation helpers mapLocale, setLocale and getLocale are exported alongside the components. FormValidator, FormValidatorGroup and Validators are in the table above.