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

manteen-kit

v0.2.1

Published

Author Mantine component registries in Mantine's vocabulary and compile them to an interchange format any registry client can read.

Downloads

751

Readme

manteen-kit

Author Mantine component registries in Mantine's vocabulary; compile them to an interchange format any registry client can read.

For a complete repository layout, multi-file item, publishing workflow, direct-URL install and configured-namespace workflow, follow the registry-authoring guide.

bun add -d manteen-kit

Ships as Node-compatible ESM and requires Node >= 20.11. Any package manager works; authoring the registry in Bun is optional.

Why

Registries distribute code you're meant to own and edit — the composed layer on top of a component library, not the library itself. Mantine has no such tooling, and the established interchange format is shaped around a different design system: roughly a third of its item schema (tailwind, cssVars, css, style, baseColor, iconLibrary, theme, font) is inert for Mantine, and it can't express a version gate, a provider requirement, a theme fragment, or Styles API selectors.

This kit lets you write the former and emit the latter.

manteen.registry.json   ← your schema, your vocabulary
      │  manteen-kit build
      ▼
r/*.json                ← interchange format, machine-readable

Nothing you author mentions the wire vocabulary — it exists only in generated output. That keeps the output installable by any client that speaks the format while leaving the authoring layer entirely Mantine-shaped.

CLI

manteen-kit build [catalog.json] [outDir]      # default: ./manteen.registry.json → ./public/r
manteen-kit merge-theme <base.ts> <fragment.ts> [--write] [--prefer incoming] [--json]

build validates the catalog against the authoring schema and every emitted item against the vendored interchange schema, exiting non-zero on either.

Authoring format

{
  "name": "base",
  "namespace": "@base",              // bare `uses` names are qualified with this
  "items": [
    {
      "name": "data-grid",
      "kind": "block",               // component | block | hook | lib | theme | file
      "mantine": ">=9",              // version GATE, checked — not an install directive
      "provider": true,              // requires MantineProvider
      "npm": ["@mantine/core@^9"],
      "uses": ["empty-state"],       // bare = this registry; "@other/x" = cross-registry
      "files": [
        { "path": "src/data-grid.tsx", "as": "component" },
        { "path": "src/use-data-grid.ts", "as": "hook" }
      ],
      "themeFragment": "src/data-grid.theme.ts",
      "docs": "Usage, source and attribution notes carried into the compiled item."
    }
  ]
}

Unknown fields are rejected rather than dropped, so the authoring format can't quietly drift toward the wire format.

docs is copied into the installable item document. Use it for human-facing usage, source and attribution notes; it is not a substitute for shipping any license notice required with copied source.

stylesApi is an optional author assertion for a component that genuinely exposes named selectors through a public classNames/styles interface. Private CSS-module class names do not qualify, and the kit carries the declaration without trying to infer or verify the component implementation:

{ "stylesApi": { "DataGrid": ["root", "header", "row"] } }

props and usage are the same kind of author assertion, for documentation clients. props documents the prop surface (keyed by exported component or hook name, each entry name/type plus optional required/default/description); usage names a copy-ready example module that is inlined at build time. The kit carries both verbatim — it never infers documentation from source — and usage, like themeFragment, is deliberately not listed in files, so no client installs it:

{
  "props": { "DataGrid": [{ "name": "rows", "type": "DataGridRow[]", "required": true }] },
  "usage": "src/data-grid.usage.tsx"
}

mantine, provider, themeFragment, stylesApi, props and usage have no direct wire-format equivalent, so they compile into the installable item JSON under the open meta.mantine object. The registry index contains only the discovery-safe requires and provider summary; stylesApi and the inlined theme fragment remain item-detail metadata. Clients that understand these fields act on them; clients that do not still install the files correctly.

themeFragment is deliberately not listed in files: an unaware client must not drop a stray theme module into a project, and an aware one merges it instead.

Theme composition

The interchange format merges its own theme variables into a consumer's project. Mantine's theme.ts has no equivalent, so a registry-shipped theme could only be overwritten wholesale — one theme item per project, local edits lost on update.

manteen-kit merge-theme src/lib/theme.ts fragment.ts --write

| Case | Behavior | | --- | --- | | Component missing from base | inserted, import added in the file's existing sort order | | Component in both | .extend() objects merged, so defaultProps compose | | Same leaf set by both | existing kept, conflict reported (--prefer incoming flips it) | | Callback classNames/styles/vars | never merged — reported, since composing them changes runtime semantics | | Entry that isn't X.extend({...}) | reported, left alone |

Comments and formatting survive; inserted nodes match the base file's indent and comma style. Idempotent, so it's safe to run on every install.

Programmatic API

import { compileRegistry, mergeThemeSource, validateCatalog } from "manteen-kit";

const { source, items, index, failures } = compileRegistry("./manteen.registry.json");
const { text, conflicts } = mergeThemeSource(baseSource, fragmentSource);

Multiple registries

One toolchain, any number of catalogs — paths inside a catalog resolve against its own directory:

manteen-kit build registries/base/manteen.registry.json    dist/base
manteen-kit build registries/product/manteen.registry.json dist/product

An item in @product can declare uses: ["@kit/callout", "@base/empty-state"], and a client resolves across all of them in one install. fixtures/ contains exactly this arrangement and the test suite exercises it.

Known limitation

Items are deduplicated by destination path, so two registries publishing an item of the same name collide — the last one installed wins, silently. If @base/empty-state and @house/empty-state have different prop signatures, install order decides which one your project gets. Namespace item names, or don't ship overlapping names across registries you expect to be installed together.

License

MIT