Components
document:docs/componentsList every team's UI components on the company site, from Storybook or any other tool.
Components
Section titled “Components”Each team keeps its components in the tool it already uses. The company site lists every component, who owns it and which other teams built one of the same name, and links into each team’s tool. The components stay where they are.
A repository publishes by committing autocatalog.components.json. Anything can
write that file: a plugin, or your own script. The catalog reads the file and
knows nothing about the tool behind it.
Publish from Storybook
Section titled “Publish from Storybook”Install the plugin, and turn on the component manifest in .storybook/main.ts.
Storybook leaves it off by default, and without it the site has stories but no
props or descriptions:
npm install -D autocatalog-plugin-storybookconst config: StorybookConfig = { // … features: { componentsManifest: true },};Build Storybook, then write the file and commit it:
npx storybook buildnpx ac from-storybook storybook-static --url https://storybook.acme.dev/checkout/Props come from whichever docgen engine the build used. A build with
features.experimentalDocgenServer can write stories with no props, and the
command says so.
--url says where the Storybook is deployed. Without it, the site lists the
component with no link to its stories. Later runs keep the address and owner
already committed, so a rebuild names neither. Nothing about the machine that
built it goes in the file.
Fail a pull request when the file no longer matches the components:
npx storybook buildnpx ac from-storybook storybook-static --checkPublish from anything else
Section titled “Publish from anything else”Write a plugin, or write the file yourself.
autocatalog-core/contracts/autocatalog.components.schema.json describes it:
{ "viewer": { "name": "Gallery", "url": "https://gallery.acme.dev/" }, "owner": "Mobile", "components": [ { "id": "receipt-card", "name": "ReceiptCard", "description": "The receipt in the mobile app.", "props": [], "stories": [{ "id": "receipt-card--paid", "name": "paid", "link": "#receipt-card/paid" }] } ]}viewer.name labels the links, and each story’s link joins onto viewer.url.
Owners
Section titled “Owners”owner names one team for every component in the file. Without it, CODEOWNERS
names each component’s owner from its source file. ac from-storybook --owner
sets owner.
How components compose
Section titled “How components compose”A component is a resource in the graph, as an event is, so what reads the graph reads components:
/catalog.jsoncarries them, and--indexjoins them into another site./ownerslists them under their team, and the catalog explorer finds them.- A lock pins them with the rest of the repository, and a tag moves them. Each package in a monorepo can publish a file of its own.
What the site shows
Section titled “What the site shows”/componentslists each component with its repository, owner and story count, and marks a name that more than one repository publishes./components/<repository>/<id>/has the import line, props and stories, with a link to each in the team’s tool./components/<repository>/<id>.mdis the same for agents.llms.txtlists every component andllms-full.txtincludes each one.
A repository whose documents are all invalid still publishes its components: the documents are left out by name.
The site compares whole names across repositories. Two components of one name can do different things, so the mark says where to look.
A worked example
Section titled “A worked example”examples/components
has three Storybook teams and one team with a format of its own, read by a plugin
in the example. pnpm verify:components publishes them as one site.