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

@forthtilliath/forth-ui

v0.5.0

Published

Higher-level, opinionated React components built on top of [`@forthtilliath/shadcn-ui`](../shadcn-ui) primitives. Where shadcn-ui gives you the building blocks (`Button`, `Popover`, `Command`, ...), forth-ui assembles them into complete, batteries-include

Readme

@forthtilliath/forth-ui

Higher-level, opinionated React components built on top of @forthtilliath/shadcn-ui primitives. Where shadcn-ui gives you the building blocks (Button, Popover, Command, ...), forth-ui assembles them into complete, batteries-included patterns — a Combobox built from Popover + Command, a PasswordInput with a strength meter, a Dropdrawer that's a DropdownMenu on desktop and a Drawer on mobile — so you don't have to wire the same recipe from scratch in every project.

62 components across 8 categories, styled with Tailwind CSS and class-variance-authority, fully typed, and browsable in Storybook (pnpm run dev:sb from the repo root).

Table of contents

Why forth-ui

  • Complete patterns, not just primitives. Every component solves a whole problem — form field wiring (Field), file upload with previews (Dropzone, ImageInput), an imperative confirm dialog (useConfirm) — instead of leaving the composition to each consumer.
  • Consistent variants. Every component that has visual variants uses the same class-variance-authority shape (variant, size, look, shape, ...), so once you've learned one component's API, the others feel familiar.
  • One folder, one subpath import. No barrel file dragging in the whole library — import { Combobox } from "@forthtilliath/forth-ui/components/combobox" pulls in exactly that component's code.
  • Distributable like shadcn. Every component (but Grid, see Registry) is also published as a shadcn-compatible registry item, so it can be vendored source-first into a consuming project instead of installed as an opaque node_modules dependency.

Installation

Via npm

npm install @forthtilliath/forth-ui

@forthtilliath/shadcn-ui (the primitives forth-ui is built on) is a regular dependencies entry, not a peer — it's installed automatically, no need to add it yourself.

Import the compiled stylesheet once, alongside your component imports:

import "@forthtilliath/forth-ui/styles/globals.css";

It covers forth-ui's components and the shadcn-ui ones they're built on (Dialog, Popover…) — not every shadcn-ui component. If your app also uses others directly (Sidebar, Table…), or has its own Tailwind build anyway, use the Theming setup instead: your Tailwind then scans both packages.

As a workspace package (this monorepo)

Within this monorepo, forth-ui is consumed the same way, just via the pnpm workspace protocol instead of a published version range:

{
  "dependencies": {
    "@forthtilliath/forth-ui": "workspace:*"
  }
}

Components are built to dist/ (./components/* → ./dist/components/*/index.js), so run pnpm run build (or dev) in this package after source changes for consumers to pick them up.

Via the shadcn registry

Every component also ships as a shadcn registry item — the source files land directly in your project (components/forth-ui/<name>/), import-rewritten to your own components.json aliases, exactly like npx shadcn add button does for the official shadcn/ui components:

npx shadcn add <registry-url>/combobox.json

Add forth-ui as a named registry in your components.json to use the short form instead:

{
  "registries": {
    "@forth-ui": "<registry-url>/{name}.json"
  }
}
npx shadcn add @forth-ui/combobox

Cross-component dependencies (e.g. Combobox depending on another forth-ui component) and shadcn primitives (e.g. Popover) are declared as registryDependencies and resolve automatically — shadcn add cascades and installs everything the component needs. See apps/shadweb for how the registry itself is built.

Usage

import { Field } from "@forthtilliath/forth-ui/components/field";
import { Combobox } from "@forthtilliath/forth-ui/components/combobox";

function Example() {
  return (
    <Field label="Framework" description="Pick the one you use most.">
      <Combobox
        options={[
          { value: "react", label: "React" },
          { value: "vue", label: "Vue" },
        ]}
        placeholder="Select a framework..."
      />
    </Field>
  );
}

Language

Built-in labels (aria-labels, default placeholders, empty states, the Pagination and ConfirmDialog buttons…) are available in French (the default) and English. For a bilingual site, set the language once with UiLocaleProvider; a component's own locale prop wins over it, and its text props (placeholder, emptyMessage, ariaLabel, a ConfirmDialog's cancelLabel…) still override individual strings.

import { UiLocaleProvider } from "@forthtilliath/forth-ui/locale";

<UiLocaleProvider locale={lang /* "fr" | "en" */}>{children}</UiLocaleProvider>;

// or per component:
<Spinner locale="en" />;

UI_MESSAGES (same entry point) holds every label, grouped by component. Components rendered from shadcn-ui as-is (e.g. a Dialog's close button) keep shadcn's English text.

Components

Grouped the same way as the Storybook sidebar (forth-ui/<Category>/...).

Layout

| Component | Import | Description | | ------------------- | ---------------------------- | ----------------------------------------------------------------------------- | | Accordion | components/accordion | A vertically stacked set of interactive headings that each reveal a section. | | BentoGrid | components/bento-grid | A CSS-grid layout for unevenly-sized cards ("bento box" layouts). | | Collapsible | components/collapsible | An interactive component which expands/collapses a single panel. | | Grid, Grid.Item | components/grid | CSS-grid layout helpers with a built-in debug overlay. | | InfiniteScroll | components/infinite-scroll | Calls onLoadMore once a sentinel scrolls into view. | | Marquee | components/marquee | Infinitely scrolls its children (a logo wall, a ticker). | | Reparent | components/reparent | Moves children between different container elements at different breakpoints. | | Repeat | components/repeat | Repeats a component a specified number of times. | | ScrollShadow | components/scroll-shadow | A vertically-scrollable container with fade-out edge shadows. | | Separator | components/separator | Visually or semantically separates content. | | Spacer | components/spacer | Adds space between components — a flexible filler or a fixed gap. | | Stepper | components/stepper | A numbered sequence of steps for a multi-stage flow. |

Navigation

| Component | Import | Description | | ---------------------------- | ----------------------- | ------------------------------------------------------------------------- | | Breadcrumb | components/breadcrumb | Displays the path to the current resource using a hierarchy of links. | | Link, LinkPreview | components/link | A styled hyperlink, plus a hover-triggered metadata preview card. | | Navbar | components/navbar | A fixed, floating page header that shrinks on scroll, plus a mobile menu. | | Pagination | components/pagination | Navigates between pages, computing visible page numbers and ellipses. | | Scrollspy (useScrollspy) | components/scrollspy | Tracks which element id is currently scrolled into view. |

Buttons & Actions

| Component | Import | Description | | ----------------------------- | ------------------------ | ------------------------------------------------------------------------------- | | Button, ButtonGroup | components/button | A button, or a component that looks like one, plus joined button rows/columns. | | Chip | components/chip | A compact, interactive element for status, categories, or filters. | | ModeToggle, ThemeProvider | components/mode-toggle | A light / dark / system theme switcher (needs the optional next-themes peer). |

Forms

| Component | Import | Description | | ------------------------- | --------------------------- | ------------------------------------------------------------------------ | | CheckboxGroup | components/checkbox | A group of checkboxes sharing a single array value. | | ColorPicker | components/color-picker | A color swatch + hex input, synced with the native color picker. | | Combobox, MultiSelect | components/combobox | An autocomplete/searchable select, and its multi-value variant. | | DatePicker | components/date-picker | A single-date picker built on a Popover + Calendar recipe. | | Dropzone | components/dropzone | A drag-and-drop file upload zone, listing accepted files below. | | Field | components/field | Wires a label, description and error message to a single form control. | | ImageInput | components/image-input | A click-to-upload image picker with a live preview. | | NumberInput | components/number-input | A numeric input with increment/decrement stepper buttons. | | PasswordInput | components/password-input | A password Input with a show/hide toggle, plus a strength meter. | | RadioCard | components/radio | A card-style RadioGroup item — the whole card is the clickable target. | | Rating | components/rating | A star rating control with keyboard navigation and hover preview. | | SubmitButton | components/submit-button | A submit Button that shows its own loading state via useFormStatus. | | TagsInput | components/tags-input | A flexible input for adding/removing multiple tags. | | ToggleSwitch | components/toggle-switch | An on/off switch with an optional visible label and description. |

Feedback

| Component | Import | Description | | -------------------- | -------------------------------- | ----------------------------------------------------------------------- | | Alert | components/alert | Displays a callout for user attention. | | Badge | components/badge | Displays a badge or a component that looks like a badge. | | Banner | components/banner | A full-width, page-level announcement bar. | | CountAnimation | components/count-animation | Animates a number counting up (or down) to a value whenever it changes. | | MultiStepLoader | components/multi-step-loader | A full-screen overlay stepping through loading messages. | | NotificationCenter | components/notification-center | A bell-icon trigger with an unread badge, opening a notification list. | | Progress | components/progress | Displays an indicator showing the completion progress of a task. | | ScrollProgress | components/scroll-progress | A fixed bar tracking scroll percentage of the page or a container. | | Spinner | components/spinner | An accessible loading indicator, in one of a few visual styles. |

Overlays

| Component | Import | Description | | ---------------- | ---------------------------- | ----------------------------------------------------------------------------------- | | CommandPalette | components/command-palette | A global command menu (Cmd/Ctrl+K to open). | | useConfirm | components/confirm-dialog | An imperative await confirm({...}) alternative to hand-wiring an AlertDialog. | | CopyMenuItem | components/copy-menu-item | A DropdownMenuItem that copies a value and briefly shows a checkmark. | | Dropdrawer | components/dropdrawer | A menu that renders as a DropdownMenu on desktop and a bottom Drawer on mobile. |

Data Display

| Component | Import | Description | | ------------------------------ | ----------------------------- | ------------------------------------------------------------------------ | | Avatar, AvatarGroup | components/avatar | An image with a fallback, status/badge indicators, and stacked grouping. | | ColumnMenu (useDndSensors) | components/column-menu | A dropdown to show/hide and reorder (drag and drop) a table's columns. | | DescriptionList | components/description-list | A description list, with terms and descriptions. | | FileList | components/file-list | Displays a list of files with name, size, and upload progress. | | GradientFrame | components/gradient-frame | A visual laid on an offset, gradient-filled frame. | | IconBubble | components/icon-bubble | An icon inside a round, tinted bubble. | | Kbd | components/kbd | Displays which key or combination of keys performs a given action. | | QrCode | components/qr-code | Generates a QR code from a string, rendered as inline SVG. | | RelativeTime | components/relative-time | Displays a live-updating time, defaulting to the local timezone. | | Sortable | components/sortable | A drag-to-reorder list built on native HTML5 drag events. | | ThemeImage | components/theme-image | An image with a light and a dark version (as={Image} for Next.js). | | Timeline | components/timeline | A vertical sequence of dated events, connected by a line. | | Tree | components/tree | A hierarchical, expandable/collapsible list of nodes. |

Code & Content

| Component | Import | Description | | ----------- | ----------------------- | ---------------------------------------------------------------- | | CodeBlock | components/code-block | A syntax-highlighted code block with a copy-to-clipboard button. | | Snippet | components/snippet | Displays and copies code in a tabbed interface. |

Conventions

  • One folder per component, matching the exports: "./components/*" map — folders that export more than one related component (Avatar + AvatarGroup, Combobox + MultiSelect, Button + ButtonGroup, Link + LinkPreview) still ship as a single import path.
  • Variants via class-variance-authority. Components with visual variants keep them in a co-located variants.ts, exporting both the cva() call and its VariantProps type (e.g. BadgeVariants).
  • Multi-part className. Components with more than one internal element accept className as an object instead of a string, keyed by part ({ root?, trigger?, content?, ... }), so you can target exactly the part you need without fighting specificity.
  • fallback/children-first fallbacks, not silent empty states — e.g. Avatar's fallback prop is required, not optional.

Theming

forth-ui has no styles of its own beyond Tailwind utility classes and the CSS variables (--primary, --muted, --border, ...) already defined by @forthtilliath/shadcn-ui's theme. Theming forth-ui means theming shadcn-ui — swap the CSS variables (or the whole theme preset) and every forth-ui component follows.

Setup

In your app's CSS entry point, import the base stylesheet, then a theme from @forthtilliath/shadcn-ui/styles/themes/*.css — each one just redeclares the same :root custom properties, so importing it after the base file overrides the default colors via normal CSS cascade:

@import "@forthtilliath/shadcn-ui/styles/globals-static.css";
@import "@forthtilliath/shadcn-ui/styles/themes/rose.css";
@import "@forthtilliath/forth-ui/styles/sources.css";

Don't add your own @import "tailwindcss"; — globals-static.css already does that internally.

What sources.css does, and why it's needed: Tailwind only generates CSS for class names it can actually find, as literal text, in the files it scans — by default your own project source, honoring .gitignore (which is why node_modules is skipped). But forth-ui and shadcn-ui ship pre-built: their component code — the literal "bg-primary", "rounded-md", etc. strings — only exists in their compiled dist/ files. Without registering them explicitly, none of those classes would be generated and the components would render unstyled. sources.css does that with @source for forth-ui's components and, through shadcn-ui's own sources.css, for the shadcn-ui ones they're built on.

Its paths are relative to the package itself, so it works whatever the node_modules layout. Don't write the @source yourself with a glob such as ../node_modules/@forthtilliath/*/dist/**/*.js: under pnpm (packages are symlinks — junctions on Windows) that pattern silently matches nothing.

Available themes

19 themes ship under @forthtilliath/shadcn-ui/styles/themes/, all rendered here with the same components (light and dark mode).

The first 11 are tweakcn-generated — most of them only change the colors:

| Theme | Style | Light | Dark | | -------------- | -------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------- | | default | shadcn's neutral default: black on white, grey accents. | default theme, light | default theme, dark | | blue | The default look with a blue primary. | blue theme, light | blue theme, dark | | bubblegum | Candy pink and pastels, Poppins, hard offset shadows. | bubblegum theme, light | bubblegum theme, dark | | claymorphism | Soft clay: warm greys and indigo, very round, pillowy shadows. | claymorphism theme, light | claymorphism theme, dark | | green | The default look with a green primary. | green theme, light | green theme, dark | | orange | The default look with an orange primary. | orange theme, light | orange theme, dark | | red | The default look with a red primary. | red theme, light | red theme, dark | | rose | The default look with a rose primary. | rose theme, light | rose theme, dark | | twitter | Twitter blue, Open Sans, very round corners. | twitter theme, light | twitter theme, dark | | violet | The default look with a violet primary. | violet theme, light | violet theme, dark | | yellow | The default look with a yellow primary. | yellow theme, light | yellow theme, dark |

The other 8 go further: besides fonts, radius and shadows, each adds signature effects — plain CSS rules on shadcn-ui's data-slot attributes (pixel frames, scanlines, frosted glass, hand-drawn outlines…), active only while the theme is imported. The components themselves are untouched, and focus stays visible (a theme restyling a button's shadow gets an outline instead). Their fonts fall back to system stacks; load the fonts named at the top of each file (Google Fonts, next/font…) for the full look.

| Theme | Style | Light | Dark | | ----------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------- | | brutalist | Neo-brutalism: thick black outlines, hard offset shadows, buttons that press in, dotted paper. | brutalist theme, light | brutalist theme, dark | | pixel | 8-bit: notched pixel frames, pixel type, checkerboard — Game Boy greens (light), PICO-8 night (dark). | pixel theme, light | pixel theme, dark | | crt | CRT monitor: amber phosphor, scanlines and vignette, glowing text, blinking cursor. | crt theme, light | crt theme, dark | | synthwave | Synthwave: sunset sky over a perspective grid, chrome titles, neon gradient buttons. | synthwave theme, light | synthwave theme, dark | | glass | Glassmorphism: frosted translucent surfaces floating over a colorful gradient mesh. | glass theme, light | glass theme, dark | | sketch | Hand-drawn: wobbly inked outlines and handwriting — lined notebook (light), chalkboard (dark). | sketch theme, light | sketch theme, dark | | newspaper | Newspaper: newsprint and ink, Didone headlines over double rules, halftone dots, small caps. | newspaper theme, light | newspaper theme, dark | | memphis | Memphis pop: confetti pattern, asymmetric corners, squiggly underlined titles, colored hard shadows. | memphis theme, light | memphis theme, dark |

Development

pnpm run dev            # concurrently: tsc --watch + tailwind --watch
pnpm run build          # tsc + tailwind build -> dist/
pnpm run check-types    # tsc --noEmit
pnpm run lint           # eslint

Every component has a matching Storybook story under apps/react-sb/src/stories/forth-ui — run pnpm run dev:sb from the repo root to browse them all, organized into the same 8 categories as this README.

Registry

apps/shadweb/scripts/generate-forth-ui-registry.ts regenerates the registry from this package's source — never hand-edit apps/shadweb/registry/forth-ui/** directly. From apps/shadweb:

pnpm run registry:generate  # source -> apps/shadweb/registry/forth-ui + registry.json
pnpm run registry:build     # registry.json -> public/r/*.json (shadcn build)
pnpm run registry:sync      # both, in order

Grid is intentionally excluded — it depends on @forthtilliath/react-kit and @forthtilliath/ts-types, external npm packages that aren't inlined into the registry item yet.

License

MIT