Distribution

Registry

The /r/index.json + /r/{slug}.json contract.

The Fancy UI registry is a public, JSON-only HTTP contract that lets anyone — humans, agents, third-party tooling — discover and download component source. The site you're reading runs it at https://ui.particle.academy/r/ and the schema is intentionally compatible with shadcn's so adjacent tooling that already speaks the format works out of the box.

Endpoints

Path Returns
/r/index.json The registry index — every installable component, lightweight summary.
/r/{slug}.json One registry-item — full source bundle for that component.

Both endpoints are public, cacheable, and CORS-open (Access-Control-Allow-Origin: *). They cache for 5 minutes at the edge and 15 minutes at our origin. They contain no secrets and no user data.

The index — /r/index.json

{
  "$schema": "https://ui.particle.academy/schema/registry.json",
  "name": "fancy-ui",
  "homepage": "https://ui.particle.academy",
  "items": [
    {
      "name": "card",
      "type": "registry:ui",
      "title": "Card",
      "description": "Card from react-fancy",
      "package": "react-fancy",
      "files": 6,
      "url": "/r/card.json"
    },
    ...
  ]
}

Each item carries enough to render in a list or run substring search against. The url points at the full bundle for that component.

The bundle — /r/{slug}.json

{
  "$schema": "https://ui.particle.academy/schema/registry-item.json",
  "name": "card",
  "type": "registry:ui",
  "title": "Card",
  "description": "...",
  "package": "react-fancy",
  "dependencies": ["clsx", "tailwind-merge"],
  "registryDependencies": ["utils-cn"],
  "files": [
    {
      "path": "components/fancy/card/Card.tsx",
      "content": "import { forwardRef } from \"react\";\n...",
      "type": "registry:ui",
      "target": "components/fancy/card/Card.tsx"
    },
    ...
  ]
}

Field reference

Field Type Description
name string Globally unique slug (kebab-case).
type string One of registry:ui, registry:hook, registry:lib, registry:block.
title string The display name (TitleCase).
description string One-line summary.
package string Which Fancy UI package this component lives in. Informational; the bundle is self-contained.
dependencies string[] npm packages the component imports. Peer deps (react, react-dom, tailwindcss) are filtered out.
registryDependencies string[] Other registry slugs this component imports from. Resolves recursively.
files object[] The source files to write.

File entries

Field Type Description
path string Original path within the bundle.
content string The raw source code.
type string Same vocabulary as the top-level type.
target string Where the file should land in the consumer's codebase. Relative to the aliases.components path in fancy.json.

How consumers use it

The reference consumer is the fancy-cli CLI but anything that speaks HTTP can use it.

Manual fetch

curl -s https://ui.particle.academy/r/card.json | jq .files[].path
# "components/fancy/card/Card.tsx"
# "components/fancy/card/Card.types.ts"
# "components/fancy/card/CardBody.tsx"
# "components/fancy/card/CardFooter.tsx"
# "components/fancy/card/CardHeader.tsx"
# "components/fancy/card/index.ts"

CLI

npx fancy-cli@latest add card

MCP

Agents in any IDE that speaks the Fancy UI MCP server can browse and install components conversationally:

"Add the card and dropdown components to my project."

The MCP server reads the registry on the agent's behalf and applies the writes.

Recursive dependency resolution

If a component bundle lists registryDependencies, consumers should fetch and install those too, recursively. The CLI and MCP server both do this — they collect the full dependency tree before applying writes so partial installs aren't possible.

The graph is a DAG. We deliberately avoid cycles in our own registry.

Self-hosting

Any HTTP server that exposes /r/index.json + /r/{slug}.json in this schema is a valid registry. The CLI accepts a registry URL in fancy.json:

{
  "registry": "https://my-company.example.com"
}

You could host a private mirror that only has your internal company components, or one that overrides specific Fancy UI components with your team's forks. Mixing multiple registries (e.g. ours + yours) is on the CLI roadmap.

What this is not

  • It's not an npm replacement. The bundles are source-code distribution, not a package format. You don't require() a registry-item; the CLI copies it into your codebase.
  • It's not a build artifact source. The content strings are the raw .tsx we ship in our repo, not transpiled. Your bundler compiles them like any other source file.
  • It's not authenticated. There's nothing private in the registry — it's a public CDN-friendly contract.