Skip to content

Repository files navigation

EventCatalog Federation: an organization example

This repository shows how an organization can let teams own separate EventCatalogs while publishing one organization-wide catalog.

This guide covers the new built-in, lockfile-based Federation commands. It does not use the older @eventcatalog/generator-federation copy generator.

What Federation is

Federation combines independently owned catalogs without moving their source documentation into one repository.

  • A team catalog owns and versions its domains, systems, services, messages, schemas, and other documentation.
  • A federating catalog selects the team catalogs that belong in its view.
  • EventCatalog resolves relationships between those catalogs and builds one connected catalog.
  • A lockfile pins every source to a commit, so local and CI builds use the same documentation.
flowchart LR
  subgraph Teams[Team-owned repositories]
    PAY[Payments catalog]
    ORD[Orders catalog]
    FUL[Fulfillment catalog]
  end

  PAY -->|index and content| FED[Organization catalog]
  ORD -->|index and content| FED
  FUL -->|index and content| FED

  FED --> LOCK[eventcatalog.lock]
  FED --> SITE[One connected documentation site]
Loading

The organization catalog is a composition point, not the owner of every document. Teams still review and change their documentation through their normal repositories.

How it works

Federation runs three stages before dev, build, or generate:

  1. Index — describe each catalog's resources, relationships, files, and content hashes.
  2. Resolve — join the indexes into one graph and resolve references across catalog boundaries.
  3. Hydrate — fetch the pinned files and write them to the generated federated/ directory.
flowchart LR
  A[Team catalogs] --> B[Build or fetch indexes]
  B --> C[Resolve one graph]
  C --> D{Ownership conflicts?}
  D -->|Yes| E[Stop the build]
  D -->|No| F[Hydrate pinned content]
  F --> G[Build the catalog]
Loading

If a source repository contains catalog.index.json, EventCatalog uses it. Otherwise, EventCatalog checks out the source and creates the index itself.

Catalogs in this example

Each directory is a standalone EventCatalog project.

Directory Owner Scope
customer-identity Customer Identity Team Profiles, authentication, sessions, and addresses
catalog Product Catalog Team Products, categories, and search indexing
pricing-and-promotions Pricing & Promotions Team Prices, promotions, and coupons
cart-and-checkout Checkout Experience Team Carts, checkout orchestration, and tax
orders Order Management Team Orders, order history, and lifecycle
payments Payments Platform Team Payments, refunds, fraud, and providers
fulfillment Fulfillment Operations Team Inventory, warehouses, shipping, and carriers
platform Developer Platform Team Runtime, CI/CD, observability, and developer tooling
central-catalog Reviews & Trust Team The federated view and organization-owned reviews documentation

Every resource, team, and user in this example has one owning catalog. The central catalog owns only the Reviews domain and its Reviews & Trust team; the other domains stay in their team catalogs and appear in the organization view through Federation.

Set up Federation

1. Prepare each team catalog

Each team needs a valid EventCatalog in a GitHub repository. The catalog can be at the repository root or in a subdirectory.

Before adding sources, agree on these rules:

  • Every resource ID has one owning catalog across the organization.
  • All versions of a resource stay with the same owning catalog.
  • Shared users and teams are defined once, not copied into every catalog.
  • Consumers reference another team's resource by ID; they do not create a second MDX definition for it.
  • When migrating from the copy generator, remove copied resources and dependency placeholders that repeat an owner's ID.

These rules matter because Federation rejects duplicate IDs and type collisions instead of choosing a winner.

2. Prepare the federating catalog

Use an EventCatalog release that provides the built-in commands:

npx eventcatalog federation --help

Federation is an EventCatalog Enterprise feature. Make the Scale license key available to local commands and CI:

export EVENTCATALOG_SCALE_LICENSE_KEY=your-license-key

Keep generated files out of Git by adding these entries to the federating catalog's .gitignore:

federated/
.eventcatalog-cache/

Commit eventcatalog.lock; do not ignore it.

3. Add a source catalog

Run commands from the federating catalog:

cd central-catalog
npx eventcatalog federation add github:acme/payments-catalog

If the catalog is inside the source repository, pass its path:

npx eventcatalog federation add github:acme/payments --path catalog

This repository demonstrates the monorepo pattern. Multiple catalogs use the same GitHub repository, so each source also needs a unique ID:

npx eventcatalog federation add github:acme/federation-organization-example \
  --path payments \
  --id acme/payments

npx eventcatalog federation add github:acme/federation-organization-example \
  --path orders \
  --id acme/orders

Repeat the command for each team catalog. federation add:

  • checks the new source against sources already added;
  • reports duplicate ownership and unresolved references;
  • adds the source to eventcatalog.config.js; and
  • pins the source commit and index digest in eventcatalog.lock.

Use --dry-run to check a source without changing either file:

npx eventcatalog federation add github:acme/payments --path catalog --dry-run

The generated configuration has this shape:

export default {
  // The rest of the catalog configuration
  federation: {
    sources: [
      {
        id: 'acme/payments',
        source: 'github:acme/payments',
        path: 'catalog',
        mode: 'hydrate',
      },
    ],
  },
};

The built-in GitHub source currently uses the github:owner/repository locator. The machine running Federation must be able to fetch the repository and its raw files.

4. Check and run the catalog

npx eventcatalog federation status
npm run dev

status shows the pinned commit, mode, age, resource count, conflicts, and references that are not yet federated.

dev, build, and generate automatically prepare the federated content from eventcatalog.lock. Do not edit anything under federated/; it is replaced on the next run.

Connect resources across catalogs

A consumer references the ID owned by another team. For example, the Fulfillment catalog can receive an event owned by Payments:

---
id: fulfillment-service
name: Fulfillment Service
version: 1.0.0
receives:
  - id: payment-captured
    version: 1.0.0
---

Only Payments defines the payment-captured event. Fulfillment does not copy the event or create a placeholder resource. The reference can remain external while working on the team catalog; it resolves when both sources are present in the federating catalog.

Version behavior is predictable:

  • no version or latest selects the highest available version;
  • an exact version selects that version; and
  • a semantic version range selects the highest matching version.

A reference to a missing ID is reported but does not block adding the source. Duplicate ownership, conflicting resource types, and pointer type mismatches do block the federated build.

Choose a source mode

Mode Behavior Use it when
hydrate Fetches the remote documentation, schemas, specifications, sidecars, and assets into federated/ Users need the remote resource pages in this catalog. This is the default.
reference Keeps the source in the resolved graph but does not write its remote files The graph relationship is needed but the remote documentation should not be materialized.

Set the mode when adding or updating a source:

npx eventcatalog federation add github:acme/payments --path catalog --mode reference

Organization patterns

One catalog per team repository

Each team keeps its catalog with its code and the organization catalog federates those repositories. This gives teams independent review and release cycles and is the clearest default for most organizations.

A catalog in a repository subdirectory

Keep documentation beside a service or product using a folder such as catalog/, then add it with --path catalog. This avoids creating a documentation-only repository.

Multiple catalogs in one monorepo

Use a different --path and --id for every catalog. This repository uses that layout. A source ID must be stable because it is recorded in the lockfile and federation graph.

A thin organization catalog

Let teams own implementation-level resources. Keep only organization-wide material in the central catalog, such as cross-domain flows, architecture decisions, shared taxonomy, and global teams or users.

Several composed views

The same team catalog can be a source for more than one federating catalog. For example, an organization can publish a company view and smaller business-unit views without copying the team documentation.

Ownership and conflict rules

  • IDs are organization-wide identifiers, not repository-local identifiers.
  • One source owns an ID and all of its versions.
  • Local content in the federating catalog must not reuse an ID owned by a source.
  • Cross-catalog relationships use pointers such as sends, receives, services, domains, flows, and flow steps.
  • Assets under public/ and components/ should use distinct paths. Different files at the same shared path produce a collision warning.
  • Adding a source with an ownership conflict writes nothing. Fix the ownership boundary, then add it again.

Update and deploy

Federated builds do not silently move to the latest source commit. To update a source, rerun its federation add command:

npx eventcatalog federation add github:acme/payments --path catalog

Review and commit the resulting eventcatalog.config.js and eventcatalog.lock changes. CI then installs the central catalog and builds it with the Scale license key:

npm ci
npm run build

This produces a repeatable release: the config says which catalogs participate, and the lockfile says exactly which version of each catalog was used.

Troubleshooting

Message or symptom What to do
eventcatalog.lock is missing Run eventcatalog federation add for the configured sources and commit the lockfile.
Source ... is not in the lockfile Add that source again so its config and lock entry agree.
Ownership conflict Remove the copied or placeholder resource from the non-owning catalog, or assign a different globally unique ID.
Reference is not yet federated Add the owning catalog, or correct the referenced ID or version.
Federated content looks stale Rerun federation add for the source to pin its new commit, then rebuild.
Federation cannot fetch content Check the github: locator, --path, repository access, and source commit.

Explore a team catalog without Federation

Each team catalog can still run on its own:

cd cart-and-checkout
npm run dev

Build an individual catalog with:

cd payments
npm run build

About

Example of how EventCatalog Federation would work in an organization across many teams or domains

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages