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

matchcn

v0.2.2

Published

A semantic index across shadcn-format component registries: find a component by what it does, not what it is called.

Readme

matchcn

A semantic index across shadcn-format component registries: find a component by what it does, rather than what it is called.

Homepage: matchcn.dev

matchcn is an independent, unofficial project. It is not affiliated with, endorsed by, or a partner of shadcn, any of the registries it indexes, or classifier.dev/TypeSafe.

What it is

Hundreds of registries now publish components in the shadcn registry.json format, and npx shadcn add can install from any of them. No developer or coding agent can hold that many registries in context, and existing directory tools only search component names, which does not help when you know what you need but not what any given registry decided to call it. matchcn tags every component across a fixed set of properties (category, motion, visual density, interaction model, and two others) using classifier.dev, then matches a plain-language brief against those tags with deterministic code, so the same brief always ranks the same way.

Status: early, read this before using it

This is a 2-3 day MVP covering 11 of the 372+ registries shadcn's own public list currently has. It is not a comprehensive index. Specific, known weak points, in order of how much they matter:

  • Some registries are partly or fully excluded for paywalled components, found by a real per-item availability check (does npx shadcn add actually work unauthenticated, not just what the index claims): aceternity (163 of 282 tagged components, 163 of 170 registry:block page-templates, 95.9% of that type) and shadcn-dashboard (165 of 508) had the gated share filtered out before shipping; the full tagged sets remain preserved, not lost (docs/DECISIONS.md #12). shadcnblocks was tagged (4,171 components) but is held back entirely: its own filter check got contaminated by the vendor's rate limiter (docs/ROADMAP.md), so it ships once a clean check runs rather than on bad data. cult-ui.com isn't indexed at all: its registry sits behind a bot challenge (docs/DECISIONS.md #6).
  • Tag confidence varies by registry and dimension, and the matcher already accounts for it. visual_density is the weakest dimension overall (36% of pilot answers under 0.6, docs/PILOT_REPORT.md). Catalog-wide, 24.4% of choice-dimension answers scored under 0.6 as of the 1,783-component measurement, not yet recomputed for the current 3,717-component catalog (a 20-item pre-tagging sample for cnippet/uiable scored 35% under 0.6, higher than that baseline). assistant-ui is the lowest- confidence registry measured (37.0% under 0.6), likely because its agent/chat UI content sits furthest from the schema's original motion/marketing anchors. A confidence-weighted matcher discounts all of this automatically, so a weak tag pulls its own weight down instead of producing a wrong confident answer, but a brief leaning heavily on these registries or on visual density is the one most likely to get a shortlist or no-match instead of a clean pick.
  • Non-English briefs are known to be weaker, confirmed on 3 Polish test briefs, not fixed. A Polish pricing brief and its English equivalent were compared directly: English found a real, well-tagged pricing component at 0.98 confidence, Polish returned no match at all. A zero-cost fix was tried and tested properly on 3 Polish briefs: it did not help, made one brief measurably worse, and left one unchanged, so it was reverted for no measured benefit. Non-English input should not be assumed to work. Details: docs/DECISIONS.md #17.

None of these cause a wrong forced answer: when confidence is genuinely low, pick_component returns a shortlist or an explicit no-match, never a single silent guess. That is the actual point of the tagging and ranking design, not a disclaimer bolted on afterward. See docs/DEMO_REPORT.md for real examples of all three outcomes, including two briefs designed to fail.

Install

npx matchcn

MCP setup

Add to your MCP client's config (for example Claude Desktop's claude_desktop_config.json, or Claude Code's .mcp.json):

{
  "mcpServers": {
    "matchcn": {
      "command": "npx",
      "args": ["-y", "matchcn"]
    }
  }
}

This exposes one tool, pick_component(brief, registry?, maxResults?).

Worked example

$ pnpm demo

Brief: a dense bento grid for a landing page. This is real output from a real run. classifier.dev does not guarantee identical answers across calls, so the exact confidence number will vary between runs (0.79 to 0.98 observed across repeated runs during development); the outcome, the chosen component, and the install command have been stable across every run tried.

BRIEF: a dense bento grid for a landing page
----------------------------------------------------------------------
OUTCOME: CONFIDENT
Selected "bento-grid" from magicui.

  -> bento-grid  (magicui)  confidence 0.85
    install: npx shadcn@latest add https://magicui.design/r/bento-grid.json
    matched:     category, motion, visual_density, interaction_model, needs_external_data, decorative_only
    not matched: (none)

resolve used: true   decisions spent: 7

Every response includes a per-dimension reason (which of the six tagged dimensions matched the brief and which did not), never just a name. Full JSON shape and more examples, including a shortlist and two deliberate no-match cases: docs/DEMO_REPORT.md.

How it works

Five stages: Ingest, Tag, Match, Resolve, Surface. Tagging runs ahead of time and is committed as reviewable JSON (data/tags/); matching at query time is deterministic code, not a model call, so the same brief always ranks the same way. Full architecture, every design decision and its rejected alternatives, and the exact tagging criteria used:

Registries indexed, and attribution

matchcn stores only derived tags (category, motion, density, and so on) and a link back to each registry's own install command. It never copies, stores, or redistributes any registry's component source code. Every component you install still comes directly from its own registry via npx shadcn add <url>.

| registry | homepage | components indexed | |---|---|---| | react-bits | reactbits.dev | 204 | | magicui | magicui.design | 79 | | aceternity | ui.aceternity.com | 119 | | kokonutui | kokonutui.com | 51 | | animate-ui | animate-ui.com | 420 | | motion-primitives | motion-primitives.com | 33 | | shadcn-dashboard | shadcndashboard.dev | 343 | | assistant-ui | assistant-ui.com | 154 | | bundui | bundui.io | 217 | | cnippet | ui.cnippet.dev | 1128 | | uiable | uiable.com | 969 |

3,717 components total, drawn from the eleven registries above (343 of shadcn-dashboard's 508 tagged components ship, the other 165 filtered out as paywalled; 119 of aceternity's 282 tagged components ship, the other 163 filtered out as paywalled; see the limitations section above for both). The first six are the motion/marketing family from the original MVP; the rest are a product-UI expansion (forms, tables, dashboards, data display) added after per-registry filter verification, see docs/REGISTRY_EXPANSION_STEP1_2.md. Three other product-UI candidates (shadcn-ui-blocks, plate, react-aria) were evaluated and excluded for specific, evidenced filter gaps; shadcnblocks was tagged but is not currently shipped, both tracked in docs/ROADMAP.md. cnippet and uiable were added in a second product-UI expansion; two other candidates from that same recon, shadcnuikit and shadcn-space, were evaluated and excluded after a real per-item availability check found genuine paywalls on 40% and 33.3% of a 30-item sample respectively. uiable's descriptions are largely name-echo templates ("X component.") rather than hand-written text, a known limitation for that registry, shipped as is rather than blocked on. Tagging runs through classifier.dev, a free, keyless classification endpoint backed by TypeSafe's Jev decision model.

Development

pnpm install
pnpm ingest      # fetch and normalize all registries
pnpm tag         # tag all components via classifier.dev
pnpm demo        # run 3 briefs end to end
pnpm test        # determinism tests for the matcher
pnpm typecheck

License

MIT, see LICENSE.