Catalog Graph logo

Backstage Catalog Graph Plugin

Created by SDA SE

Catalog Graph adds a visual map to your Backstage catalog. It shows how your entities connect across ownership, APIs, groups, and dependencies. You get a quick read on what touches what, so you can reason about impact and trace responsibility without leaving your portal.

The plugin offers two main views. There is a card on each entity that surfaces direct neighbors for fast context. There is a full page that lets you explore the wider graph. You can filter by kind or relation, change layout direction, set max depth, and choose how edges render. This keeps large catalogs readable while you zoom or step through the model.

Engineers use it to answer common questions during everyday work. What services consume this API. Who owns that job. What systems this change could affect. It helps with onboarding since new teammates can see the landscape in minutes. It supports discovery work too, like finding unknown dependencies before a migration or audit. The UI builds on the catalog’s relation model, so it fits naturally with how Backstage stores and queries data.

If you already run Backstage with a populated catalog, Catalog Graph gives you a clear picture of your ecosystem with low ceremony. It is simple to adopt in stages. Start with the entity card for quick wins, then open the page view when you need deeper exploration.

Backstage Catalog Graph Plugin showing relationships between entities

Installation Instructions

These instructions apply to self-hosted Backstage only. To use this plugin on Roadie, visit the docs.

What you get

This plugin is frontend only. There is no backend package to install.

You can use it in two frontend setups

  • legacy app system
  • new frontend system

Follow the section that matches your app. You can install both safely. The plugin will work in either setup.

Legacy app system

  1. Add the dependency to your app

    Copy
    yarn --cwd packages/app add @backstage/plugin-catalog-graph
  2. Add the Catalog Graph page route in packages/app/src/App.tsx

    Copy
    // packages/app/src/App.tsx
    import React from 'react';
    import { createApp } from '@backstage/app-defaults';
    import { FlatRoutes } from '@backstage/core-app-api';
    import { Route } from 'react-router-dom';
    import { CatalogGraphPage, catalogGraphPlugin } from '@backstage/plugin-catalog-graph';
    import { catalogPlugin } from '@backstage/plugin-catalog';
    
    const app = createApp({
      bindRoutes({ bind }) {
        bind(catalogGraphPlugin.externalRoutes, {
          catalogEntity: catalogPlugin.routes.catalogEntity,
        });
      },
    });
    
    const AppProvider = app.getProvider();
    const AppRouter = app.getRouter();
    
    export const App = () => (
      <AppProvider>
        <AppRouter>
          <FlatRoutes>
            {/* other routes */}
            <Route path="/catalog-graph" element={<CatalogGraphPage />} />
          </FlatRoutes>
        </AppRouter>
      </AppProvider>
    );

    Optional initial filters

    Copy
    <Route
      path="/catalog-graph"
      element={
        <CatalogGraphPage
          initialState={{
            selectedKinds: ['component', 'domain', 'system', 'api', 'group'],
          }}
        />
      }
    />
  3. Add the graph card to your entity page so users can see relations on each entity

    Copy
    // packages/app/src/components/catalog/EntityPage.tsx
    import React from 'react';
    import Grid from '@material-ui/core/Grid';
    import { EntityCatalogGraphCard } from '@backstage/plugin-catalog-graph';
    
    export const OverviewContent = () => (
      <Grid container spacing={3}>
        {/* other cards */}
        <Grid item md={6} xs={12}>
          <EntityCatalogGraphCard variant="gridItem" height={400} />
        </Grid>
      </Grid>
    );

    Optional arrow heads for edges

    Copy
    <EntityCatalogGraphCard variant="gridItem" height={400} showArrowHeads />
  4. Optional custom relations
    Register the default API with your own relation list in packages/app/src/apis.ts

    Copy
    // packages/app/src/apis.ts
    import { createApiFactory } from '@backstage/core-plugin-api';
    import {
      ALL_RELATIONS,
      ALL_RELATION_PAIRS,
      catalogGraphApiRef,
      DefaultCatalogGraphApi,
    } from '@backstage/plugin-catalog-graph';
    
    export const apis = [
      createApiFactory({
        api: catalogGraphApiRef,
        deps: {},
        factory: () =>
          new DefaultCatalogGraphApi({
            knownRelations: [...ALL_RELATIONS, 'myRelationOf', 'myRelationFor'],
            knownRelationPairs: [
              ...ALL_RELATION_PAIRS,
              ['myRelationOf', 'myRelationFor'],
            ],
            defaultRelationTypes: {
              exclude: ['myRelationOf', 'myRelationFor'],
            },
          }),
      }),
      // other APIs
    ];
  5. Optional custom node rendering on the page

    Copy
    // packages/app/src/App.tsx
    import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
    import { MyCustomRenderNode } from './components/MyCustomRenderNode';
    
    <Route
      path="/catalog-graph"
      element={<CatalogGraphPage renderNode={MyCustomRenderNode} />}
    />
  6. Optional custom node rendering on the card

    Copy
    // packages/app/src/components/catalog/EntityPage.tsx
    import { EntityCatalogGraphCard } from '@backstage/plugin-catalog-graph';
    import { MyCustomRenderNode } from '../MyCustomRenderNode';
    
    <EntityCatalogGraphCard
      variant="gridItem"
      height={400}
      renderNode={MyCustomRenderNode}
    />
  7. Optional direct use of the lower level component if you need a fully custom view

    Copy
    // any component file
    import React from 'react';
    import { EntityRelationsGraph, Direction } from '@backstage/plugin-catalog-graph';
    
    export const MyGraph = () => (
      <EntityRelationsGraph
        rootEntityNames={{ kind: 'Component', namespace: 'default', name: 'my-service' }}
        maxDepth={2}
        direction={Direction.LEFT_RIGHT}
        mergeRelations
        unidirectional
      />
    );

New frontend system

  1. Add the dependency to your app

    Copy
    yarn --cwd packages/app add @backstage/plugin-catalog-graph
  2. Enable the entity relations card in app-config.yaml
    The card is not enabled by default

    Copy
    # app-config.yaml
    app:
      packages: all
      extensions:
        - entity-card:catalog-graph/relations

    Optional card config

    Copy
    # app-config.yaml
    app:
      extensions:
        - entity-card:catalog-graph/relations:
            config:
              title: 'Entities Relations Graph'
              height: 400
              maxDepth: 1
              unidirectional: true
              mergeRelations: true
              direction: LR
              zoom: enabled
  3. The graph page is enabled by default
    You can change the path

    Copy
    # app-config.yaml
    app:
      extensions:
        - page:catalog-graph:
            config:
              path: '/entity-graph'

    Optional initial filters on the page

    Copy
    # app-config.yaml
    app:
      extensions:
        - page:catalog-graph:
            config:
              initialState:
                selectedKinds: ['component', 'domain', 'system', 'api', 'group']
                maxDepth: 2
                unidirectional: true
                mergeRelations: true
                direction: LR
                curve: curveStepBefore
  4. Optional route bindings in config
    Bind the external entity page reference if your app uses a non default entity route
    Or point another plugin route to the catalog graph page

    Copy
    # app-config.yaml
    app:
      routes:
        bindings:
          catalog-graph.catalogEntity: catalog.catalogEntity
          some-plugin.some-external-route: catalog-graph.catalogGraph
  5. Optional feature discovery rules per environment

    Copy
    # app-config.production.yaml
    app:
      packages:
        include:
          - '@backstage/plugin-catalog-graph'
    Copy
    # app-config.local.yaml
    app:
      packages:
        exclude:
          - '@backstage/plugin-catalog-graph'
  6. Optional direct use of exported components in custom code

    Copy
    // you can still import and render the page or card in custom modules
    import { CatalogGraphPage, EntityCatalogGraphCard } from '@backstage/plugin-catalog-graph';

Things to Know

Features

The plugin comes with these features:

  • EntityCatalogGraphCard: A card that displays the directly related entities to the current entity. This card is for use on the entity page. The card can be customized, for example filtering for specific relations.

  • CatalogGraphPage: A standalone page that can be added to your application providing a viewer for your entities and their relations. The viewer can be used to navigate through the entities and filter for specific relations. You can access it from the EntityCatalogGraphCard. NB: you will need to supply props to this component to tell it what root Entity to display when it renders like so:

Copy
{
  "initialState": {
    "rootEntityRefs": [
      "domain:customers",
      "domain:employees"
    ],
    "maxDepth": 1,
    "selectedRelations": [
      "dependsOn"
    ]
  }
}
  • EntityRelationsGraph: A react component that can be used to build own customized entity relation graphs.

Prerequisites

The plugin will only display relationship that have already been set up between entities. You will need to define these yourself for services, api’s etc… in the catalog.yaml files.

i.e.

Copy
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: wayback-search
  description: Search of the wayback machine
spec:
  type: service
  lifecycle: production
  owner: team-a
  providesApis:
    - wayback-search
  consumesApis:
    - wayback-archive

For more, please check out this post on how to model software in Backstage.

Changelog

This changelog is produced from commits made to the Catalog Graph plugin since 3 months ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.

Features

  • Add an API to customize which catalog relations the graph supports and shows by default. The UI now autocompletes custom relations. Default behavior stays the same. #30889 20 days ago
  • Add i18n support to the catalog graph plugin. You can localize labels and messages. #30074 3 months ago

Bug fixes

  • Fix graph sizing issues in DependencyGraph. Stop indefinite rerender that spiked CPU. The graph now measures size correctly. The Fullscreen button now floats without taking layout space. Contained fit now sizes the inner svg correctly. #31168 13 days ago
  • Fix crash in NFS apps due to a missing catalog graph API implementation. Provide a default implementation so the plugin works in NFS again. #31201 16 days ago

Set up Backstage in minutes with Roadie