Pavan Rangani

HomeBlogBackstage Developer Portal: Building Internal Platforms in 2026

Backstage Developer Portal: Building Internal Platforms in 2026

By Pavan Rangani · February 26, 2026 · DevOps & Cloud

Backstage Developer Portal: Building Internal Platforms in 2026

Backstage Developer Portal: Building Your Internal Platform

Spotify created the Backstage developer portal to solve a real problem: hundreds of microservices, dozens of teams, and no single place to find documentation, ownership, or deployment status. Open-sourced in 2020 and now a CNCF incubating project, it has become the de facto standard for internal developer portals. This guide covers everything from initial setup to production deployment with custom plugins.

Why Developer Portals Matter in 2026

As organizations scale beyond 50 microservices, developers spend increasingly more time searching for information than writing code. Who owns this service? Where are the docs? How do I deploy? What’s the API contract? Without a central hub, these questions eat hours every week. Moreover, onboarding new engineers becomes painful when tribal knowledge lives in Slack threads and wikis nobody maintains.

Backstage solves this by providing a single pane of glass — a software catalog that tracks every service, library, and piece of infrastructure your organization runs. Furthermore, it offers scaffolding templates that let developers spin up new services following your organization’s golden paths, and a plugin ecosystem that integrates with your existing tools.

Backstage developer portal team workspace
Backstage brings together service catalogs, documentation, and developer tools in one portal

Setting Up Backstage from Scratch

Getting started requires Node.js 18+ and Yarn. The CLI scaffolds a complete application with a frontend, backend, and example plugins. Additionally, Backstage uses a PostgreSQL database in production (SQLite for development).

# Create a new Backstage app
npx @backstage/create-app@latest my-portal
cd my-portal

# Start in development mode
yarn dev

# Project structure
# packages/app/     - React frontend
# packages/backend/ - Node.js backend
# app-config.yaml   - Main configuration
# catalog-info.yaml - This repo's catalog entry

The configuration file app-config.yaml controls everything: database connections, authentication providers, catalog locations, and plugin settings. For production, you’ll want to configure GitHub or GitLab authentication and point the catalog at your organization’s repositories.

# app-config.production.yaml
app:
  baseUrl: https://backstage.yourcompany.com
backend:
  baseUrl: https://backstage.yourcompany.com
  database:
    client: pg
    connection:
      host: localhost
      port: 5432
      user: backstage
      password: ${POSTGRES_PASSWORD}
auth:
  providers:
    github:
      development:
        clientId: ${GITHUB_CLIENT_ID}
        clientSecret: ${GITHUB_CLIENT_SECRET}
catalog:
  locations:
    - type: url
      target: https://github.com/your-org/*/blob/main/catalog-info.yaml

The Software Catalog: Heart of Backstage

Every entity in your organization — services, libraries, APIs, teams, infrastructure — gets a catalog-info.yaml file in its repository. This file describes what the component is, who owns it, and how it relates to other components. The catalog then aggregates all these files into a searchable, browsable directory.

# catalog-info.yaml for a microservice
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  description: Handles payment processing and billing
  annotations:
    github.com/project-slug: your-org/payment-service
    backstage.io/techdocs-ref: dir:.
    pagerduty.com/service-id: PXXXXXX
  tags:
    - java
    - spring-boot
    - payments
  links:
    - url: https://grafana.yourcompany.com/d/payment-service
      title: Grafana Dashboard
      icon: dashboard
spec:
  type: service
  lifecycle: production
  owner: team-payments
  system: billing-platform
  providesApis:
    - payment-api
  consumesApis:
    - user-api
    - notification-api
  dependsOn:
    - resource:payment-db
    - component:auth-service

The power of the catalog lies in its relationship model. You can see which services depend on each other, which team owns what, and how APIs connect consumers to providers. This visibility alone prevents countless incidents caused by unexpected dependencies.

Entity Kinds and the Catalog Data Model

To use the catalog effectively, it helps to understand the small but expressive vocabulary of entity kinds. A Component is a thing you build and run, such as a service or a library. An API describes a contract that components provide or consume. A Resource represents infrastructure such as a database or queue, while System and Domain group related components into coherent business areas. Finally, Group and User entities model your org chart so ownership resolves to real people.

These kinds are not decorative — they drive the graph that makes Backstage valuable. For instance, because payment-service declares providesApis: [payment-api], any component that lists consumesApis: [payment-api] automatically shows up as a downstream dependency. Consequently, when an on-call engineer investigates an incident, they can trace the blast radius without grepping through dozens of repositories.

One common edge case is orphaned entities. If a repository is deleted but its catalog location still points at the old URL, the entity lingers with a processing error. Therefore, production teams typically enable orphan cleanup and configure the catalog processor to deduplicate entities that share the same name across multiple locations. Getting ownership and lifecycle fields right early prevents a slow drift into an untrustworthy catalog.

Software catalog dashboard analytics
The software catalog maps relationships between services, teams, and infrastructure

Backstage Developer Portal: TechDocs for Living Documentation

TechDocs is Backstage’s built-in documentation system based on MkDocs. It renders Markdown files stored alongside your code directly in the portal. The key benefit: documentation lives with the code it describes, so developers update docs in the same pull request that changes the code.

# docs/mkdocs.yml in your service repo
site_name: Payment Service
nav:
  - Home: index.md
  - Architecture: architecture.md
  - API Reference: api.md
  - Runbooks:
    - Deployment: runbooks/deployment.md
    - Incident Response: runbooks/incidents.md
    - Database Migrations: runbooks/migrations.md
plugins:
  - techdocs-core

In production, configure TechDocs to build documentation in CI/CD and publish to cloud storage (S3, GCS, or Azure Blob). This avoids building docs on-the-fly and keeps the Backstage instance lightweight. Moreover, the recommended “external” build strategy separates the documentation pipeline entirely from the portal, so a broken docs build never degrades the catalog experience.

Software Templates: Golden Paths for New Services

Templates let developers create new projects following your organization’s standards. Instead of copying an old repo and removing half the code, developers fill out a form and get a properly configured repository with CI/CD, monitoring, and documentation already set up.

# template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: spring-boot-service
  title: Spring Boot Microservice
  description: Create a production-ready Spring Boot service
spec:
  owner: platform-team
  type: service
  parameters:
    - title: Service Details
      properties:
        name:
          title: Service Name
          type: string
          pattern: '^[a-z][a-z0-9-]*
		
		
	


        description:
          title: Description
          type: string
        owner:
          title: Owner Team
          type: string
          ui:field: OwnerPicker
    - title: Infrastructure
      properties:
        database:
          title: Database
          type: string
          enum: [postgresql, mysql, none]
        messaging:
          title: Message Broker
          type: string
          enum: [kafka, rabbitmq, none]
  steps:
    - id: fetch
      name: Fetch Template
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          description: ${{ parameters.description }}
    - id: publish
      name: Create Repository
      action: publish:github
      input:
        allowedHosts: ['github.com']
        repoUrl: github.com?owner=your-org&repo=${{ parameters.name }}
    - id: register
      name: Register in Catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

The real leverage of templates is consistency. Because every new service is born already registered in the catalog, with ownership, runbooks, and CI wired in, the portal never falls behind reality. If you are formalizing these golden paths across teams, the broader discipline is covered in our platform engineering guide.

Building Custom Plugins

Backstage’s plugin architecture lets you extend the portal with custom functionality. Common plugins include cost dashboards, deployment status, incident management, and security scanning results. Creating a plugin is straightforward — it’s a React component that renders inside the Backstage shell.

// plugins/cost-dashboard/src/components/CostOverview.tsx
import { useEntity } from '@backstage/plugin-catalog-react';
import { useApi } from '@backstage/core-plugin-api';
import { costApiRef } from '../api';

export const CostOverview = () => {
  const { entity } = useEntity();
  const costApi = useApi(costApiRef);
  const serviceName = entity.metadata.name;

  const { data, loading } = useAsync(
    () => costApi.getMonthlyCost(serviceName),
    [serviceName]
  );

  if (loading) return <Progress />;

  return (
    <InfoCard title="Monthly Cloud Cost">
      <Typography variant="h3">
        {data.totalCost.toFixed(2){"}"}/month
      </Typography>
      <Typography color="textSecondary">
        Compute: {data.compute.toFixed(2){"}"} |
        Storage: {data.storage.toFixed(2){"}"} |
        Network: {data.network.toFixed(2){"}"}
      </Typography>
    </InfoCard>
  );
};

Since the introduction of the new backend system, plugins are wired together through a dependency-injection-style API that registers extension points rather than monkey-patching the app. As a result, upgrades are far less brittle than they were in the early days. Still, plugin maintenance is the hidden cost of Backstage: every plugin you write becomes code your platform team owns, tests, and upgrades across breaking changes. Therefore, prefer community plugins where they exist and reserve custom development for genuinely differentiated functionality.

Developer portal plugin development
Custom plugins extend Backstage with organization-specific functionality

Production Deployment Patterns

For production, deploy Backstage as a containerized application with a PostgreSQL database. Use Kubernetes for orchestration, and set up proper authentication, RBAC, and monitoring. The community recommends separating the frontend and backend for independent scaling.

# Dockerfile for production
FROM node:18-bookworm-slim AS build
WORKDIR /app
COPY . .
RUN yarn install --frozen-lockfile
RUN yarn tsc
RUN yarn build:backend

FROM node:18-bookworm-slim
WORKDIR /app
COPY --from=build /app/packages/backend/dist ./
COPY --from=build /app/app-config.yaml ./
RUN yarn install --production
EXPOSE 7007
CMD ["node", "packages/backend", "--config", "app-config.yaml"]

Additionally, set up health checks, configure proper logging with structured JSON output, and integrate with your existing monitoring stack. Backstage exposes Prometheus metrics out of the box, making it easy to track catalog size, plugin performance, and API response times. For multi-tenant installations, the built-in permission framework lets you gate sensitive actions — such as registering catalog locations or executing templates — behind policy checks tied to group membership.

Backstage vs Alternatives: Port, Cortex, and OpsLevel

While Backstage is the most popular open-source option, commercial alternatives exist. Port offers a no-code portal builder with a visual catalog. Cortex provides scorecards and service maturity tracking. OpsLevel focuses on service ownership and standards compliance. Backstage wins on flexibility and community ecosystem but requires more engineering investment to set up and maintain. For teams with strong platform engineering capabilities, it is typically the best choice. For teams wanting faster time-to-value with less customization, a commercial tool may be more appropriate.

When NOT to Adopt Backstage: Honest Trade-offs

Backstage is genuinely powerful, but it is not free in either sense of the word. The single biggest mistake teams make is adopting it without a dedicated owner. It is a framework, not a finished product — you are expected to write integration code, theme the UI, and maintain plugins through frequent breaking releases. Consequently, a small organization with ten services and two teams will almost certainly get more value from a hosted commercial portal, or even a well-maintained README index, than from standing up Backstage.

There are other warning signs. If your engineering culture resists keeping catalog-info.yaml files current, the catalog rots and developers stop trusting it. Likewise, if you cannot commit to ongoing upgrades, you will eventually find yourself pinned to an old version with security and dependency debt. In short, treat Backstage as a long-term product investment with staffing attached. When that investment is realistic, the payoff is substantial; when it is not, simpler tooling serves you better.

Key Takeaways

For further reading, refer to the AWS documentation and the Google Cloud documentation for comprehensive reference material.

  • Start with the software catalog — discoverable ownership and docs provide immediate value
  • Add templates for your most common service patterns to enforce golden paths
  • Use TechDocs so documentation lives with the code and stays current
  • Reserve custom plugins for genuinely differentiated functionality
  • Staff a dedicated owner and budget for ongoing upgrades

Backstage transforms how organizations manage their software ecosystem. Start with the software catalog — just getting ownership and documentation discoverable provides immediate value. Then add templates for your most common service patterns and TechDocs for living documentation. Finally, build custom plugins that surface the metrics and tools your developers actually need. The investment pays off quickly as your organization scales beyond a handful of services.

In conclusion, the Backstage developer portal is an essential topic for modern software development. By applying the patterns and practices covered in this guide, you can build more robust, scalable, and maintainable systems. Start with the fundamentals, iterate on your implementation, and continuously measure results to ensure you are getting the most value from these approaches.

← Back to all articles