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

@maholan/registry

v0.3.0

Published

MHL UI component registry — builds JSON served by the CLI

Readme

@maholan/registry

Component registry builder for the MHL Untitled UI Platform. Reads registry.json (the source manifest), inlines component source files from packages/ui, and outputs individual JSON files consumed by @maholan/cli.


What This Package Does

This package is a build-time tool — it is not published to npm and has no runtime exports. Its sole job is to produce the public/r/*.json files that the CLI fetches when a consumer runs npx @maholan/cli add <component>.

registry.json          ← source manifest (edited by humans)
src/build.ts           ← build script
         │
         ▼  pnpm build
public/r/
├── index.json         ← full registry index
├── button.json        ← Button component (source inlined)
├── button-stories.json
└── ...                ← one file per registry item

Registry Manifest (registry.json)

The manifest is the single source of truth for what components exist and where their source files live in the monorepo.

Schema

Each item in items[] follows this shape:

{
  "name": "button",
  "type": "registry:component",
  "title": "Button",
  "description": "Accessible button built on React Aria.",
  "dependencies": [
    "react-aria-components",
    "class-variance-authority",
    "clsx",
    "tailwind-merge"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/mhl/button/button.tsx",
      "sourcePath": "../ui/src/components/base/buttons/button/button.tsx",
      "type": "registry:component"
    },
    {
      "path": "registry/mhl/button/button.variants.ts",
      "sourcePath": "../ui/src/components/base/buttons/button/button.variants.ts",
      "type": "registry:component"
    }
  ],
  "cssVars": {
    "light": { "brand-600": "257 90% 58%" },
    "dark": { "brand-600": "257 90% 65%" }
  }
}

Field reference

| Field | Description | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------- | | name | kebab-case identifier — used as the CLI add argument and as the output filename (button.json) | | type | registry:component for components, registry:file for standalone files (e.g., stories) | | title | Human-readable display name | | description | Plain-English description for CLI output and LLM context | | dependencies | npm packages installed into the consumer project | | registryDependencies | Other MHL components this one depends on — resolved recursively by the CLI | | files[].path | Consumer-facing install path (written into the output JSON as-is) | | files[].sourcePath | Path relative to packages/registry/ to the source file in the monorepo — read at build time and stripped from output | | files[].target | Optional override for where the CLI writes the file in the consumer project | | cssVars | CSS custom properties introduced by this component, for both light and dark modes |

sourcePath is a build-time field. It never appears in the built JSON files consumers download. The build script reads the file at sourcePath, inlines its contents as "content", and removes sourcePath from the output.


Build

# From repo root
pnpm --filter @maholan/registry build

# From this package directory
pnpm build

The build script (src/build.ts):

  1. Reads registry.json
  2. For each item, reads every sourcePath and inlines the file content
  3. Writes one JSON file per item to public/r/<name>.json
  4. Writes public/r/index.json with the full registry index (no file content)

Output Format

public/r/<name>.json (component file)

{
  "name": "button",
  "type": "registry:component",
  "title": "Button",
  "description": "...",
  "dependencies": ["react-aria-components", "..."],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/mhl/button/button.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n...",
      "type": "registry:component"
    }
  ],
  "cssVars": { "light": {}, "dark": {} }
}

public/r/index.json (full index)

[
  {
    "name": "button",
    "type": "registry:component",
    "title": "Button",
    "description": "...",
    "dependencies": ["..."],
    "registryDependencies": []
  }
]

Deployment

public/r/ is a static directory — serve it from any HTTP host. The CLI reads the registry URL from mhl.config.json:

{
  "registries": {
    "@maholan": "https://mhl-ui.dev/r"
  }
}

The CLI fetches <registryUrl>/<name>.json for each component:

https://mhl-ui.dev/r/button.json
https://mhl-ui.dev/r/input.json

Vercel (current setup)

vercel.json in this package configures the deployment. The public/r/ directory is served at the root of the deployment.


Adding a New Component

  1. Create the component in packages/ui/src/components/<name>/ (all 5 files: .tsx, .variants.ts, .stories.tsx, .test.tsx, index.ts)
  2. Add an entry to registry.json with all fields filled in
  3. Run pnpm --filter @maholan/registry build to generate the JSON
  4. Verify public/r/<name>.json contains the correct inlined source
  5. Commit both registry.json and public/r/<name>.json

Related Packages

  • @maholan/ui — Source of all component files referenced by sourcePath
  • @maholan/cli — Fetches the built JSON files at runtime