| 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. |
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.
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.
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.
test -f AGENTS.md && cat AGENTS.md
test -f CLAUDE.md && cat CLAUDE.mdThese contain repo-specific rules that override general patterns.
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."
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:
- BUI (
@backstage/ui) — default for new plugins and new workspaces - MUI v5 (
@mui/material) — when BUI lacks the component you need - 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.
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.
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.
All backend code MUST use:
createBackendPlugin— new standalone backend capabilitiescreateBackendModule— 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.
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.yamlwiring (derived from package name) - MUI v5 class name generator required when using
@mui/materialin 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.
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.
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.
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 filesbuild: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 are required for published package changes. Rules:
- Only cover plugins under
plugins/— neverpackages/*(those are private app/backend packages that are never published) - Only include a plugin if it has changes in
src/or other published paths (rootindex.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 runyarn changesetinteractively
All commits must be signed off (git commit -s) per DCO requirements.
| 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 |
| 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 |
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-engInstall 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 |