Skip to content
Brok UI

Loading…

No results

Registry Format

The registry is the source of truth for every installable component, block, page, bundle, and theme. Each item is an item.json manifest plus one or more source files living under registry/open/ or registry/pro/. Running php artisan registry:build validates the tree, inlines file content and SHA-256 hashes, and writes JSON endpoints under public/r/<tier>/ that the ui:add CLI fetches and writes into the consumer app.

Note

This page is for registry contributors. Application teams only need the manifest field reference to read what ui:show and ui:add report.

Manifest

Every item declares itself through an item.json file at the root of its source directory. Below is the real manifest for the Button component.

registry/open/ui/button/item.json JSON
{
    "name": "button",
    "type": "registry:component",
    "title": "Button",
    "description": "Displays a button or link with variants, sizes, loading and an optional animated arrow.",
    "version": "1.2.1",
    "license": "open",
    "stability": "stable",
    "knowledge": {
        "keywords": ["action", "submit", "call to action"],
        "useWhen": ["Triggering an immediate action such as saving or submitting."],
        "avoidWhen": ["Representing a persistent on/off value; use switch or checkbox."],
        "related": ["button-group", "toggle"]
    },
    "registryDependencies": [],
    "dependencies": {
        "composer": ["jml/brok:^0.2"],
        "npm": []
    },
    "files": [
        {
            "path": "ui/button/button.blade.php",
            "target": "resources/views/components/ui/button.blade.php",
            "type": "blade"
        }
    ],
    "meta": {
        "a11y": "wcag-2.2-aa-target",
        "responsive": true,
        "rtl": true,
        "darkMode": true,
        "localized": true
    }
}

Field reference

Field Type Description
name string Slug used by the CLI (ui:add button) and as the registry key. Lowercase, hyphenated.
type string Item kind. One of registry:component, registry:block, registry:page, registry:bundle, or registry:theme. Drives target and catalog validation.
title string Human-readable display name shown in docs and the CLI confirmation prompt.
description string One-sentence summary rendered on the docs index and in ui:status output.
version string Semver string. ui:diff and ui:update compare this against what is recorded in the consumer's ui-lock.json.
contractVersion integer Version of the normalized human/agent contract emitted by the builder. Authored v2 manifests are checked against their Blade prop names and defaults.
foundationVersion semver Minimum shared ui.css/_styles.php foundation required by the item. The CLI blocks incompatible installs.
license string "open" (MIT, no auth required) or "pro" (commercial, requires ui:auth). Must match the tier directory the item lives in; the build enforces parity.
stability string Maturity signal ("experimental", "incubating", "stable", or "deprecated"). Change impact is recorded separately in migrations.
registryDependencies string[] Other registry item slugs this item requires. The CLI resolves them recursively (with a cycle guard) and installs them automatically. Open items may not depend on pro items.
knowledge object Guidance for humans and agents: keywords, use/avoid cases, anatomy, source-derived props/slots, behaviour, examples, related items, accessibility, and theming. Sparse authored data is completed by the builder.
composition object Machine-readable layout contract: kind, surface, frame, regions, responsive rules, states, and components used. Blocks and pages expose it through ui:show --skeleton.
api object Stable component props, slots, attribute forwarding, keyboard behavior, focus behavior, JavaScript requirements, validation, and Livewire compatibility. The builder derives and signs it.
accessibility object Exact component capabilities for keyboard input, focus management, focus traps, focus restoration, Escape dismissal, ARIA requirements, roles, and ARIA attributes.
examples[] object[] Versioned executable Blade examples copied from the component preview source. The CLI, MCP server, docs, and external renderers can use them without page scraping.
migrations[] object[] Structured from/to migration guidance, summary, breaking flag, optional manual steps, and optional codemod identifier.
deprecation object Required when stability is deprecated: version introduced, replacement item, removal horizon, and optional message.
dependencies.composer string[] Composer package constraints required by the item. Source manifests omit jml/brok; the builder injects the canonical release line into published items, and the CLI enforces it before add/update. Other Composer requirements remain manifest metadata for the consumer to install.
packageConstraint string Exceptional source-only override for the builder-injected jml/brok constraint. First-party items normally omit it and inherit registry.package_constraint.
dependencies.npm string[] npm package requirements (e.g. "alpinejs:^3.0"). The CLI prints the required npm install command; it does not mutate package.json or run npm.
files[].path string Path to the source file relative to the tier root (registry/<tier>/), i.e. <kind>/<name>/<file> such as ui/button/button.blade.php. This is the single edit point for that file.
files[].target string Where the file lands in the consumer's project. Must be under resources/views/components/ui, resources/views/blocks, resources/views/pages, resources/js/ui, resources/css/themes, or public/vendor/brok (static files loaded by URL, such as the theme-script boot file). The build rejects any target outside these paths.
files[].type string File kind: "blade", "js", or "css". JS is wired into resources/js/ui/index.js; registry theme CSS receives a managed import in resources/css/ui.css.
meta object Quality signals: a11y, responsive, rtl, darkMode, localized. Displayed as capability badges in the docs UI.

The build pipeline

php artisan registry:build (the BuildRegistry command in apps/docs-registry) runs in four stages:

  1. Scan — walks every registry/<tier>/<kind>/<name>/item.json and loads the manifest.
  2. Validate — checks that every declared source file exists, targets stay inside the allowed path set, license flags match the tier, and open items carry no pro dependencies.
  3. Inline — reads each source file and embeds its UTF-8 content plus a sha256 hash directly into the published JSON so the CLI can detect transport corruption after download. (The hash is co-shipped with the content, so it guards against accidental drift, not a tampered registry — see the integrity note below.)
  4. Write — emits public/r/<tier>/<name>.json per item and a tier-level public/r/<tier>/registry.json index.

On the consumer side, ui:add <name> fetches the item JSON from the registry endpoint, writes each files[].target into the app, resolves registryDependencies recursively (a cycle guard prevents infinite loops), wires any JS files into resources/js/ui/index.js, and records the installed version in ui-lock.json.

Three places must stay in sync

A registry item is only fully "done" when it exists in all three of the following locations simultaneously. Guard tests (CatalogNavigationTest, MirrorParityTest, BlockRenderTest) enforce parity in CI and fail fast when any location is missing.

1. Registry source

registry/open/<kind>/<name>/ — the item.json manifest plus all source files. This is the single edit point. Never modify files anywhere else to "fix" the component.

2. Docs-app render + JS copy

The docs site renders each item's Blade in place from registry/ via non-prefixed anonymous component paths; there is no per-item Blade mirror. Each item's behaviour JS is copied into the docs app at its files[].target because the lazy loader can only glob resources/js/ui/**. Run php artisan registry:mirror — never hand-copy files.

3. Catalog entry

The kind-specific file under apps/docs-registry/catalog-data/ drives navigation, docs pages, and every catalog-driven guard test. An item that is installable but not listed there is invisible. Block and page render providers derive from the catalog row; do not maintain a second test list.

Note

Mirror registry JS after editing it. After editing a registry item's behaviour JS, run php artisan registry:mirror manually. Drift is gated by php artisan registry:mirror --check, which runs inside composer check and CI and exits non-zero if any shared asset or per-item JS copy diverges.

Validation rules

The build command rejects any manifest that violates the following rules. All checks also run with --dry-run so you can validate without writing output files.

  • — Every declared file must exist. Each files[].path is resolved against the item source directory; the build fails if the file is missing.
  • — Open items may not depend on pro items. Any slug in registryDependencies is checked against the tier of the dependency; cross-tier references from open → pro are rejected.
  • — Targets must stay under allowed paths. Valid prefixes are resources/views/components/ui, resources/views/blocks, resources/views/pages, resources/js/ui, resources/css/themes, and public/vendor/brok. Any other target path is rejected.
  • — Published files carry SHA-256 hashes and inlined content. The build computes a sha256 of each source file and embeds both the hash and the full file content in the published JSON. The CLI recomputes the hash on write and aborts on a mismatch. Because the hash is co-shipped with the content, this catches transport corruption and accidental drift — by itself it is not a defence against a tampered or malicious registry (an attacker who can alter the response can recompute a matching hash), and unpinned consumers rely on HTTPS transport trust to the registry host. For provenance independent of the transport, pin the publisher's Ed25519 key as registrySigningPublicKey in ui.json: both ui:add and ui:update then verify the registry index against its detached signature before trusting anything, failing closed on a missing or invalid signature, reject a replayed older index, and bind every fetched item to the signed index's per-item content hash — a shipped guarantee, not a planned one.
  • — License flags must match the source tier. An item under registry/open/ must declare "license": "open"; an item under registry/pro/ must declare "license": "pro".
  • — Names are stable install slugs. The name field is the CLI key and must match the catalog slug. Namespaced components may use a nested source path whose leaf differs from that slug, such as ai-prompt in ui/ai/prompt.

Validate locally

Run the build in dry-run mode from the apps/docs-registry directory to catch manifest errors without writing any output files:

terminal
php artisan registry:build --dry-run

To also check that shared assets and per-item JS copies are in sync with their canonical sources (useful before opening a PR):

terminal
php artisan registry:mirror --check

Item lifecycle

States and rules

proposed → experimental → stable → mature → deprecated → frozen → removed

  • Experimental items can include breaking changes after an item version increase.
  • Experimental and incubating components, blocks, and pages install into an experimental namespace.
  • Stable items cannot depend on experimental or incubating items.
  • Each unstable item records a feedback URL and adoption evidence.
  • The registry build blocks promotion when the configured adoption threshold is not met.
  • Removal needs a deprecated release and a record in registry/removed-items.json.
  • A renamed or merged item leaves an alias in registry/<tier>/aliases.json: ui:add installs the replacement and the old URLs redirect.
  • The computed engine maps the legacy incubating manifest value to experimental.

Generated evaluation

A scheduled engine evaluates each registry item and core token across adoption, quality, performance, and maintenance. It joins repository manifests, static inventory, CI quality results, runtime telemetry, contribution data, bundle budgets, contrast checks, and removal records.

The protected lifecycle queue separates the declared state from the evaluated and recommended states. A recommendation never changes source or removes an item without owner review.

Promotion evidence

Use ui:inventory --report for project and reference counts. Use the pilot survey for recommendation feedback. Record the reviewed snapshot in lifecycle.adoption.

TargetProjectsReferencesSurvey responsesScore
Incubating1313.0
Stable31034.0

Warning

The composer check shortcut in apps/docs-registry runs registry:mirror --check, Pint, and the full test suite in one command. Run it before pushing to confirm nothing is out of sync.