Skip to content

Latest commit

 

History

History
241 lines (178 loc) · 10.2 KB

File metadata and controls

241 lines (178 loc) · 10.2 KB
name rhdh-coding
description Backstage and RHDH plugin development patterns. Use when writing, modifying, or reviewing code in a Backstage or RHDH plugin — frontend components, backend services, API clients, styling, testing, entity pages, scaffolder actions, catalog processors, NFS Blueprints, dynamic plugin configuration. Also use when asked to "add a feature to a plugin", "implement a Backstage component", "create an API client", "write plugin tests", "add a backend route", "create a scaffolder action", "what plugin type should I use", or any coding task in a Backstage or RHDH codebase.

RHDH Coding

Patterns for Backstage and RHDH plugin development that agents need but can't reliably get from training data or codebase discovery alone. This covers what you'd learn after six months of getting burned by non-obvious conventions.

Before You Write Code

1. Check for existing specs

Look for a spec, PRD, or OpenSpec design for this work — in docs/plans/**/, specifications/, openspec/changes/*/, or linked from the issue. If found, use the component list and acceptance criteria as your implementation blueprint. Read references/frontend-specs.md for what good frontend specs include.

2. Discover the plugin context

Run the detection script to understand what you're working with:

python scripts/detect-rhdh-context.py --path <plugin-dir>

This reports: Backstage role, frontend system (legacy/NFS/dual), existing extensions, MUI version, dynamic plugin status, plugin ID, scalprum name.

3. Read workspace instructions

test -f AGENTS.md && cat AGENTS.md
test -f CLAUDE.md && cat CLAUDE.md

These contain repo-specific rules that override general patterns.

4. Check version compatibility

Consult ../rhdh/references/versions.md for the RHDH → Backstage version matrix. Your @backstage/* dependency versions must match the target RHDH version. Mismatched versions cause runtime errors — most commonly "Cannot read properties of undefined."

Styling: BUI First

For new plugins, use Backstage UI (@backstage/ui) with CSS Modules and BUI CSS variables. In existing plugins, match whatever the workspace already uses — if it's MUI v4, stay consistent rather than mixing libraries. Only introduce BUI in a workspace that has already adopted it or is actively migrating.

Priority for new plugins:

  1. BUI (@backstage/ui) — default for new plugins and new workspaces
  2. MUI v5 (@mui/material) — when BUI lacks the component you need
  3. MUI v4 (@material-ui/core) — legacy maintenance only

When using MUI v5 alongside BUI, add the class name generator to prevent collisions in dynamic plugin bundles:

// src/index.ts
import { unstable_ClassNameGenerator as ClassNameGenerator } from '@mui/material/className';
ClassNameGenerator.configure(name => name.startsWith('v5-') ? name : `v5-${name}`);

Icons: Use @remixicon/react (not @material-ui/icons).

Read references/bui.md for the component mapping table and CSS variable reference.

Frontend System: NFS for New Plugins

New plugins targeting RHDH 1.5+ should use the new frontend system (NFS) with Blueprints (createFrontendPlugin, PageBlueprint, EntityCardBlueprint, etc.).

Legacy system (createPlugin + createRoutableExtension) is for existing plugins not yet migrated. For migration, use the nfs-migration sibling skill.

Read references/nfs.md for Blueprint patterns, alpha export structure, and compatWrapper decisions.

Plugin Types

Not sure whether to build a page, a card, an entity tab, or a backend module? Read references/plugin-types.md for the decision guide.

Backend: New System Only

All backend code MUST use:

  • createBackendPlugin — new standalone backend capabilities
  • createBackendModule — extensions to existing plugins (catalog, scaffolder, auth)

From @backstage/backend-plugin-api. Never the legacy backend system.

Core services: httpRouter, logger, rootConfig, httpAuth, database, scheduler, permissions, discovery.

Default export is required from the entry point (src/index.ts). Missing default export is the #1 cause of "plugin not loading" in RHDH.

RHDH Dynamic Plugins

Key gotchas (read references/rhdh.md for full details):

  • Default export required from src/index.ts — missing this is the #1 cause of "plugin not loading"
  • Scalprum name must match the key in dynamic-plugins.yaml wiring (derived from package name)
  • MUI v5 class name generator required when using @mui/material in dynamic bundles
  • Auth: use fetchApi — it includes auth headers automatically. Don't implement custom auth.
  • RHDH-only Blueprints: AppDrawerContentBlueprint, GlobalHeaderMenuItemBlueprint — not upstream

references/rhdh.md covers all RHDH-specific patterns including backend modules, extension points, theming, i18n, and the common package pattern.

Analytics

BUI components (Link, ButtonLink, Tab, MenuItem, Tag, Table rows) have built-in click analytics via the Backstage Analytics API. Don't add manual captureEvent('click', ...) for these — it produces duplicates. Use noTrack prop to suppress the built-in event only when replacing it with a domain-specific verb (e.g., deploy, approve). For detailed instrumentation guidance, install the official plugin-analytics-instrumentation skill from backstage.io.

Testing

Backstage has its own test infrastructure that differs from standard React testing. Read references/testing.md for: TestApiProvider setup, renderInTestApp, entity context mocking, async component testing, accessibility testing, and common gotchas.

Before You Commit

Run these commands in order from the workspace root (e.g., workspaces/boost/). Stop on first failure — fix it before continuing. This sequence catches every CI gate locally.

yarn prettier:fix          # format code
yarn tsc:full              # full TypeScript type check
yarn build:all             # build all packages in the workspace
yarn test --watchAll=false  # run tests (disable watch mode)
yarn build:api-reports:only # generate/update API report files

API reports

build:api-reports:only generates report.api.md files for packages with public exports. These files must be committed — CI checks them. All public exports need /** @public */ JSDoc with a description (not just the bare tag).

Changesets

Changesets are required for published package changes. Rules:

  • Only cover plugins under plugins/never packages/* (those are private app/backend packages that are never published)
  • Only include a plugin if it has changes in src/ or other published paths (root index.ts, config.d.ts, package.json)
  • Changes only in dev/, tests/, __fixtures__/, or stories do NOT need a changeset for that plugin
  • Write the changeset file directly to <workspace>/.changeset/<id>.md — don't run yarn changeset interactively

Commits

All commits must be signed off (git commit -s) per DCO requirements.

Reference Index

Reference Load when...
references/frontend-specs.md Writing specs, PRDs, or OpenSpec proposals for frontend features
references/bui.md Using BUI components — mapping table, CSS variables, icons
references/plugin-types.md Deciding what type of plugin or extension to build
references/nfs.md Writing NFS code — Blueprints, package exports, compatWrapper
references/dev-app.md Plugin dev mode, full Backstage app setup, sidebar, app-config
references/testing.md Writing tests — TestApiProvider, entity mocking, a11y
references/rhdh.md RHDH-specific patterns — dynamic plugins, backend modules, i18n

Sibling Skills (rhdh-skill)

Skill Use when...
create-plugin Scaffolding a new plugin from scratch
nfs-migration Migrating an existing plugin from legacy to NFS
overlay Managing overlay packaging for the Extensions Catalog
backstage-upgrade Upgrading Backstage dependency versions
rhdh-local Running and testing plugins locally
rhdh RHDH version matrix, repo navigation, ecosystem context

Ecosystem Skills (skills.sh)

These open-source skills complement rhdh-coding with generic frontend quality patterns. Install into .fullsend/customized/skills/ or your local skills directory.

Essential:

Skill Source What it adds
ui-ux-pro-max nextlevelbuilder/ui-ux-pro-max-skill 99 UX rules — accessibility, touch targets, animation, forms, navigation
frontend-design anthropics/skills Design thinking, anti-AI-aesthetic, microcopy quality
webapp-testing anthropics/skills Playwright-based browser testing, server lifecycle

Recommended:

Skill Source What it adds
design-taste-frontend leonxlnx/taste-skill Anti-slop discipline, design inference
emil-design-eng emilkowalski/skills Animation decisions, CSS polish
npx skills add https://github.com/nextlevelbuilder/ui-ux-pro-max-skill --skill ui-ux-pro-max
npx skills add https://github.com/anthropics/skills --skill frontend-design
npx skills add https://github.com/anthropics/skills --skill webapp-testing
npx skills add https://github.com/leonxlnx/taste-skill --skill taste-skill
npx skills add https://github.com/emilkowalski/skills --skill emil-design-eng

Official Backstage Skills (backstage.io)

Install via npx skills add https://backstage.io. These cover migration and instrumentation workflows that this skill does not.

Skill Use when...
mui-to-bui-migration Migrating a plugin from MUI to BUI (component-by-component guide)
plugin-new-frontend-system-support Adding NFS support while keeping legacy working (dual entry point)
plugin-full-frontend-system-migration Fully migrating a plugin to NFS, dropping legacy
app-frontend-system-migration Migrating an entire Backstage app to the new frontend system
plugin-analytics-instrumentation Adding analytics events via Backstage Analytics API
onboard-to-openapi-server Migrating backend router to typed OpenAPI tooling