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

catalox-ui

v1.2.0

Published

Single-app Catalox catalog workspace. Standalone: set CATALOX_UI_* / APP_ID in .env (see .env.example). Embedded host: import CatalogManagerApp from "catalox-ui/app" and pass config={{ appId, cataloxApiBaseUrl, ... }}. Requires peers react, react-dom, @x1

Readme

catalox-ui

catalox-ui is the Catalox-backed catalog workspace shipped from this repository (@x12i/catalox via the embedded BFF under server/). It provides a normalized item surface, a shared shell (CataloxUiShell), and shared list/detail/create flows driven by catalog descriptors from the backend.

The catalox-ui-core package-in-tree still holds reusable contracts, registry, and adapter helpers for hosts that compose a custom registry; the default app entry is CatalogManagerApp (src/catalox-ui-app/CatalogManagerApp.tsx).


What it is

catalox-ui is a frontend package for applications that need to:

  • browse, search, and filter multiple kinds of catalog data in one place
  • view normalized item details with shared JSON, validation, and reference surfaces
  • create new items through a shared generic flow
  • display type-specific detail UI when a module provides it
  • remain fully functional in stub/local mode before real sources are available

It is not specific to any domain, editor, or backend system.


What it is not

  • Not a graph navigator
  • Not specific to any workflow engine
  • Not a backend service or schema engine
  • Not hardcoded to any catalog family

Core concepts

| Term | Definition | |---|---| | Catalog item | Any managed item normalized into CatalogItemEnvelope | | Catalog type | A registered family key, e.g. policy-template, taxonomy-node | | Envelope | The shared normalized shape all items must conform to | | Adapter | Data behavior for one type — loads, creates, validates, returns references | | Module | UI behavior for one type — label, capabilities, and optional detail/create rendering | | Registry | A map binding each catalog type key to its adapter + module |


Architecture

The framework has four layers:

┌────────────────────────────────────────────────────────┐
│  Generic shell  CataloxUiShell                         │  Layer 2 (UI)
│  Shared components  Sidebar / Inventory / Detail / …    │
├────────────────────────────────────────────────────────┤
│  Registry + adapter helpers                             │  Layer 2 (logic)
│  loadAllCatalogItems / createCatalogItemFromRegistry …  │
├────────────────────┬───────────────────────────────────┤
│  Catalog type A    │  Catalog type B  (add yours here)  │  Layer 3
│  adapter + module  │  adapter + module                  │
└────────────────────┴───────────────────────────────────┘
│  Shared contracts  types.ts / contracts.ts              │  Layer 1
└────────────────────────────────────────────────────────┘

See ARCHITECTURE.md for the full layer breakdown, import rules, and data ownership reference.


Core contracts reference

Core types and contracts live in src/catalox-ui-core/.

Primitive types (types.ts)

| Type | Values | |---|---| | CatalogItemStatus | draft · defined · in-use · gap · deprecated · invalid | | CatalogItemSourceKind | stub · derived · live | | CatalogManagerView | inventory · gaps · recent · json-stubs | | CatalogValidationSeverity | error · warning · info | | CatalogReferenceRelationType | uses · declares · requests · maps-to · derived-from |

Entity contracts (contracts.ts)

| Type | Purpose | |---|---| | CatalogItemEnvelope | Normalized item shape all adapters must produce | | CatalogManagerState | Shell state shape | | CatalogManagerCoreProps | Props for <CatalogManagerCore> | | CatalogModule | UI behavior contract per type | | CatalogAdapter | Data behavior contract per type | | CatalogModuleCapabilities | Feature flags per module | | RegisteredCatalogModule | { module, adapter } pair | | CatalogModuleRegistry | Record<string, RegisteredCatalogModule> | | CatalogTypeOption | Type option used in create flow | | CatalogReference | Cross-item reference shape | | CatalogValidationIssue | Single validation issue | | CatalogValidationResult | { ok, issues } result | | CreateCatalogItemInput | Input for item creation | | UpdateCatalogItemInput | Input for item updates |


Registry API reference

Registry helpers are exported from src/catalox-ui-core/registry.ts.

createCatalogModuleRegistry(entries)

Creates a registry from an array of { module, adapter } pairs.

  • Throws if module.type !== adapter.type for any entry
  • Throws on duplicate type keys
  • Returns CatalogModuleRegistry

getCatalogModule(registry, type)

Returns the CatalogModule for a type, or undefined if not registered.

getCatalogAdapter(registry, type)

Returns the CatalogAdapter for a type, or undefined if not registered.

getCatalogTypeOptions(registry)

Returns CatalogTypeOption[] for all registered types — used by the create flow.

getAllRegisteredCatalogModules(registry)

Returns all RegisteredCatalogModule entries as an array.


Adapter helpers reference

Adapter helpers are exported from src/catalox-ui-core/adapters.ts.

loadAllCatalogItems(registry)

Loads items from all registered adapters. Returns { items, errors }. One failing adapter does not prevent others from loading.

createCatalogItemFromRegistry(registry, input)

Creates an item by calling the adapter's createItem if available. Falls back to a default stub envelope if not.

getCatalogItemReferences(registry, item)

Returns references for an item via the adapter's getReferences. Returns [] if not implemented.

validateCatalogItem(registry, item)

Validates an item via the adapter's validateItem. Falls back to getFallbackCatalogValidationIssues if not implemented.


Bootstrapping

With your own types

import { createCatalogModuleRegistry } from './src/catalox-ui-core/registry';
// Illustrative: your shell that consumes `registry` (this repo ships CataloxUiShell + BFF by default).
import { YourCatalogShell } from './your-app/YourCatalogShell';

const registry = createCatalogModuleRegistry([
  { module: PolicyTemplateCatalogModule, adapter: policyTemplateCatalogAdapter },
  { module: TaxonomyNodeCatalogModule,   adapter: taxonomyNodeCatalogAdapter },
]);
<YourCatalogShell registry={registry} />

Default Catalox workspace (this repo)

import CatalogManagerApp from 'catalox-ui/app';
// or from source:
import CatalogManagerApp from './src/catalox-ui-app/CatalogManagerApp';

<CatalogManagerApp />

Configure appId / API base URL via host props, public/catalox-ui.config.json, or CATALOX_UI_* / APP_ID in .env (see .env.example). For tenancy and identity questions directed at Catalox, see docs/catalox-inquiry-tenancy-and-identity.md.

Note: CATALOX_APP_ID / CATALOX_STORE_ID are for the @x12i/catalox CLI and tooling; the browser resolves appId from CATALOX_UI_APP_ID or APP_ID (and store from CATALOX_UI_STORE_ID). Set the CATALOX_UI_* / APP_ID pair if you expect the UI to default without Settings.

If GET /api/catalox/bootstrap returns 409 with catalox_metadata_incomplete, Firestore catalog rows are missing required metadata (often catalogs/{id}.metadata.status). Use operator auth and POST /api/catalox/operator/repair/metadata (dry-run by default; see server/catalox/metadataRepair.ts and docs/troubleshooting-catalox-empty-inventory.md).

The embedded BFF wires createCatalox() in server/catalox/init.ts. Enable optional Catalox stores with CATALOX_UI_RENDERER_SNIPPETS=1, CATALOX_UI_PRESENTATION_PROFILES=1, and CATALOX_UI_DESIGN_OBJECTS=1 (server env) so snippet-backed renderers, presentation profiles, and scoped design objects resolve when descriptors reference them.


Stub mode vs live mode

The framework supports both modes through adapters.

Stub mode — adapters return hardcoded CatalogItemEnvelope arrays from local data. No network, no backend. Ideal for early development.

Live mode — adapters fetch real sources, normalize the results into CatalogItemEnvelope, and return them. The shell, components, and registry are unchanged.

The adapter is the only thing that changes. The core shell, shared UI, and registry API behave identically in both modes.


Adding a new catalog type

See ADDING_A_CATALOG_TYPE.md for a step-by-step guide.

The short version: implement an adapter, implement a module, register both, pass the registry to the shell.


Display layer (Catalox v2.0)

Every list card, filter chip, and detail row is driven by the catalog descriptor — presentationSpec, filterSpec, and customRenderer. The shell enriches each descriptor once at bootstrap and routes list / filters / detail through the display components in src/catalox-ui-shell/components/display/.

Precedence for what drives the UI: optional host override > backend descriptor > default derived from queryableFields + identity.

Catalog appearance is owned by the Catalox descriptor (presentationSpec, filterSpec, identity.titleField, etc.). This shell calls enrichDescriptor(descriptor, undefined) with no built-in override map. Host integrations may merge a partial CatalogDescriptorOverride at bootstrap time if needed.

For fully custom list or item UIs, register React components in src/catalox-ui-app/custom-renderer-registry.ts and reference them from the descriptor’s customRenderer.

See ARCHITECTURE.md for the full pipeline diagram, import rules, and how to add a custom renderer component.


Google service account (GOOGLE_SERVICE_ACCOUNT_BASE64)

For local development, put your Firebase service account JSON on disk only inside .env, not in source control:

  • Set GOOGLE_SERVICE_ACCOUNT_BASE64 to the base64 encoding of the raw JSON (one line, no line breaks in the env value). You can generate it from a downloaded key file with your platform’s base64 tooling.

You do not add code in this repo to read it. The Catalox / @x12i stack (via @x12i/helpers Firebase initialization) already resolves credentials from the environment: it accepts GOOGLE_SERVICE_ACCOUNT_BASE64 and the FIREBASE_SERVICE_ACCOUNT_BASE64 alias, alongside path- or JSON-based options. If this variable is set when the BFF or tooling loads .env, authentication is picked up automatically.

Operational rule: .env is for your machine and deploy secrets only. It must stay gitignored and must never be included in an npm package tarball. Prefer GOOGLE_SERVICE_ACCOUNT_BASE64 over committing a JSON file path so CI and laptops can inject the same variable without shipping key files.


Extension roadmap

The following extension points are planned for future implementation:

  • Type-specific create forms — via module.renderCreate()
  • Type-specific edit forms — via module.renderEdit(item)
  • Advanced cross-reference view — visual relationship browser
  • JSON import/export — bulk stub creation and export
  • Permissions per catalog type — capability-gated actions
  • History/versioning panel — optional per-module version tracking
  • Live fetch testing — adapter health check panel

Framework positioning

catalox-ui (and the catalox-ui-core contracts it ships) are designed to be used as a base or embed for products that manage multiple catalog types through one consistent UI, with the default path wired to Catalox and the BFF.

Fork it, register your types, and extend per-type behavior through adapters and modules — without touching the core shell.