Exploring Your Backstage Catalog Without Backstage

Exploring Your Backstage Catalog Without Backstage

Backstage has become the de facto standard for software catalogs. Thousands of organizations use it to track their services, APIs, teams, and infrastructure through catalog-info.yaml files scattered across their repositories. The format is well-designed, the ecosystem is mature, and the idea – a single catalog of everything your organization builds and operates – is genuinely powerful.

But there’s a friction point that anyone who’s worked with Backstage has felt: the catalog files themselves are opaque until you deploy them.

You write a catalog-info.yaml, push it, wait for Backstage to ingest it, navigate to the portal, and then discover that your owner reference is wrong, or you forgot the lifecycle field, or the system you referenced doesn’t exist. The feedback loop is slow. The files are just YAML – they don’t tell you anything about whether they’re correct or how they fit into the larger picture until they’re rendered by a running Backstage instance.

That’s the problem bsv solves.

Backstage catalog files have a deceptive simplicity. A basic one looks straightforward:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  description: Handles payment processing
spec:
  type: service
  lifecycle: production
  owner: group:payments-team
  system: checkout
  dependsOn:
    - component:order-service
  providesApi:
    - payment-api

But as your catalog grows, the complexity compounds. Entities reference other entities. Components belong to systems. Systems belong to domains. Groups own components. APIs are provided by one service and consumed by three others. These relationships form a graph, and that graph is invisible when you’re staring at flat YAML files in an editor.

This creates several real problems:

You can’t see the shape of your catalog. How many components sit under each system? Which domains have the most services? Is your catalog well-organized or a jumbled mess of uncategorized entities? Answering these questions requires either a running Backstage instance or a lot of manual YAML reading.

Validation happens too late. Backstage has a schema for catalog entities – required fields, valid kinds, reference formats. But you only find out about violations after deployment. A missing owner field, an invalid lifecycle value, a malformed entity reference – these are all things you could catch immediately if you had local validation.

References break silently. When a component declares owner: group:platform-team or dependsOn: component:auth-service, there’s no guarantee those referenced entities actually exist in your catalog. Backstage will eventually warn you, but by then the broken reference is committed and deployed. In a large catalog with hundreds of entities across dozens of repositories, dangling references are endemic.

Relationships are hard to trace. “What depends on this service?” is a critical question for any change. In Backstage, you can navigate the UI to find out. In the catalog files themselves, you have to grep across repositories and mentally assemble the dependency graph.

bsv is a terminal UI application that reads your catalog files directly and presents them as an interactive, navigable tree. Point it at a directory – a monorepo root, a collection of cloned repositories, a catalog folder – and it recursively discovers every catalog-info.yaml file, parses the entities, validates them, resolves their references, and renders the result in your terminal.

# Scan a directory tree for all catalog files
bsv /path/to/your/repos

# Or just run it in the current directory
bsv

What you see is a hierarchical tree organized by Domain, System, and Component, with a details panel showing metadata, ownership, lifecycle, tags, and annotations for whatever entity you’ve selected. Vim-style navigation (j/k/h/l) lets you move through the tree quickly.

But the tree view is just the starting point.

bsv validates every entity against the official Backstage JSON Schema the moment it loads. Entities with validation errors are highlighted in red in the tree, with warning symbols and error counts. Select an entity and you see exactly what’s wrong: missing required fields, invalid values, schema violations.

This moves validation from “deploy and wait” to “run and see.” You can fix catalog errors before they ever reach Backstage, the same way a linter catches code issues before they reach production.

Every entity reference in your catalog gets color-coded feedback. Green means the referenced entity exists in the loaded catalog. Yellow means it’s missing or external – it might exist in another part of your catalog that isn’t loaded, or it might be dangling. Red means the entity kind itself is unrecognized.

For large catalogs, this is transformative. Instead of wondering whether component:legacy-auth still exists or guessing whether group:platform-engineering was renamed to group:platform-team, you see the answer immediately.

Press g on any entity and bsv renders its relationship graph directly in the terminal. You see both directions: what this entity depends on, what depends on it, which APIs it provides and consumes, who owns it, what system and domain it belongs to. The graph handles all thirteen Backstage relationship types, displayed as bidirectional pairs.

This is the answer to “what would break if I changed this service?” – the same question that’s hard to answer from YAML files alone.

If your entities use Backstage’s techdocs-ref or adr-location annotations, pressing d opens an in-terminal markdown viewer. You can browse documentation without leaving the terminal or opening a browser. It’s a small feature, but it keeps you in flow when you’re exploring the catalog.

A fair question. Backstage already has a web UI, and it’s good. Why build a terminal alternative?

Speed. bsv starts instantly, scans a directory tree in milliseconds, and renders immediately. There’s no server to boot, no database to populate, no ingestion pipeline to wait for. The feedback loop is as fast as pressing Enter.

Locality. You can validate catalog files before committing them. Point bsv at your working directory while you’re editing catalog-info.yaml and press r to reload after each change. This is a development-time tool, not a deployment-time tool.

Offline capability. bsv works entirely locally. No network connection, no running Backstage instance, no API keys. It reads files from disk and that’s it.

CI integration potential. A terminal tool that validates catalog files and exits with a non-zero status on errors is a natural fit for CI pipelines. Catch catalog problems the same way you catch failing tests – before they merge.

Simplicity. It’s a single compiled Rust binary. No runtime dependencies, no configuration files, no Docker containers. Download it, run it, done.

Consider a typical scenario. You’re in a monorepo with 40 services, organized under a handful of systems and domains. A new engineer joins and wants to understand the landscape. Today, they’d either get a walkthrough from a senior engineer, browse a Backstage portal clicking through entities one at a time, or read a potentially outdated architecture document.

With bsv, they run one command and see the entire catalog as a tree. The hierarchy is immediately visible: three domains, eight systems, forty components. They can expand any branch, see which team owns what, check the lifecycle status of each service, and trace dependencies by toggling the relationship graph. In five minutes of terminal exploration, they have a mental map that would otherwise take days to build.

Or consider the maintenance scenario. You’re deprecating a service and need to know what references it. Open bsv, navigate to the service, press g, and the relationship graph shows every consumer, every dependent, every API relationship. No grepping across repositories, no querying the Backstage API, no assembling the picture manually.

Or the validation scenario. Your team has adopted Backstage and you’re adding catalog files to 20 existing repositories. Point bsv at the parent directory and instantly see which files have schema errors, which references are dangling, and which entities are missing required fields. Fix them all before a single file is committed.

bsv is built in Rust with ratatui for the terminal UI. The architecture is clean: a parser that discovers and deserializes YAML files, an entity model that normalizes references to canonical form (kind:namespace/name), a tree builder that organizes entities hierarchically, a graph module that extracts bidirectional relationships, and a validator that checks entities against the embedded Backstage JSON Schema.

The schema is compiled into the binary at build time using include_str! and initialized once via once_cell::Lazy, so validation adds negligible overhead. The file scanner uses walkdir with a smart exclusion list – node_modules, target, dist, bazel-*, and twenty other common build directories are skipped automatically, keeping scan times fast even in large monorepos.

The project is MIT-licensed and available at github.com/grahambrooks/bsv.


bsv is part of a collection of developer tools built on the principle that understanding your software should be fast, local, and visual. See also codecity for 3D codebase visualization and codemap for semantic code knowledge graphs.