rhdh backend dynamic plugin bootstrap
npx skills add https://github.com/kadel/claude-plugins --skill RHDH Backend Dynamic Plugin Bootstrap
Skill 文档
Purpose
Bootstrap a new backend dynamic plugin for Red Hat Developer Hub (RHDH). RHDH is the enterprise-ready Backstage applicationthat supports dynamic plugins – plugins that can be installed or uninstalled without rebuilding the application.
Note: This skill covers backend plugins only. Frontend dynamic plugins have different requirements (Scalprum configuration, mount points, dynamic routes) and are covered in a separate skill.
When to Use
Use this skill when creating a new backend plugin intended for RHDH dynamic plugin deployment. This includes:
- New backend API plugins
- Backend modules for existing plugins (e.g.,
catalog-backend-module-*) - Scaffolder actions and templates
- Catalog processors and providers
- Authentication modules
- Any server-side functionality for RHDH
Do NOT use this skill for:
- Frontend plugins (UI components, pages, cards)
- Frontend plugin wiring (mount points, dynamic routes)
- Themes or frontend customizations
Prerequisites
Before starting, ensure the following are available:
- Node.js 22+ and Yarn
- Container runtime (
podmanordocker) - Access to a container registry (e.g., quay.io) for publishing
Workflow Overview
- Determine RHDH Version – Identify target RHDH version for compatibility
- Create Backstage App – Scaffold Backstage app with matching version
- Create Backend Plugin – Generate new backend plugin using Backstage CLI
- Implement Plugin Logic – Write the plugin code using new backend system
- Export as Dynamic Plugin – Build and export using RHDH CLI
- Package as OCI Image – Create container image for deployment
- Configure for RHDH – Create dynamic-plugins.yaml configuration
Step 1: Determine RHDH Version
Check the target RHDH version and find the compatible Backstage version. Consult references/versions.md for the version compatibility matrix.
| RHDH Version | Backstage Version | create-app Version |
|---|---|---|
| 1.8 / next | 1.42.5 | 0.7.3 |
| 1.7 | 1.39.1 | 0.6.2 |
| 1.6 | 1.36.1 | 0.5.25 |
| 1.5 | 1.35.1 | 0.5.24 |
Ask the user which RHDH version they are targeting if not specified.
Step 2: Create Backstage Application
Create a new Backstage application using the version-appropriate create-app:
# For RHDH 1.7 (adjust version as needed)
npx @backstage/create-app@0.6.2
# Follow prompts to name the application
# This creates the monorepo structure needed for plugin development
After creation, navigate to the app directory and install dependencies:
cd <app-name>
yarn install
Step 3: Create Backend Plugin
Generate a new backend plugin using the Backstage CLI:
yarn new
When prompted:
- Select “backend-plugin” as the plugin type
- Enter a plugin ID (e.g.,
my-plugin) - The plugin will be created at
plugins/<plugin-id>-backend/
The generated plugin structure:
plugins/<plugin-id>-backend/
âââ src/
â âââ index.ts # Main entry point
â âââ plugin.ts # Plugin definition (new backend system)
â âââ service/
â âââ router.ts # Express router
âââ package.json
âââ README.md
Step 4: Implement Plugin Logic
Backend plugins must use the new backend system for dynamic plugin compatibility. The plugin entry point should export a default using createBackendPlugin() or createBackendModule().
Example plugin structure (src/plugin.ts):
import {
coreServices,
createBackendPlugin,
} from '@backstage/backend-plugin-api';
import { createRouter } from './service/router';
export const myPlugin = createBackendPlugin({
pluginId: 'my-plugin',
register(env) {
env.registerInit({
deps: {
httpRouter: coreServices.httpRouter,
logger: coreServices.logger,
config: coreServices.rootConfig,
},
async init({ httpRouter, logger, config }) {
httpRouter.use(
await createRouter({
logger,
config,
}),
);
httpRouter.addAuthPolicy({
path: '/health',
allow: 'unauthenticated',
});
},
});
},
});
export default myPlugin;
The src/index.ts must export the plugin as default:
export { default } from './plugin';
Build and verify the plugin compiles:
cd plugins/<plugin-id>-backend
yarn build
Step 5: Export as Dynamic Plugin
Use the RHDH CLI to export the plugin as a dynamic plugin package:
cd plugins/<plugin-id>-backend
npx @red-hat-developer-hub/cli@latest plugin export
This command:
- Builds the plugin
- Creates
dist-dynamic/directory with the dynamic plugin package - Configures dependencies (peer vs bundled)
- Generates config schema
The CLI automatically handles:
- Shared dependencies:
@backstage/*packages become peerDependencies - Bundled dependencies: Non-backstage deps are bundled in the package
- Embedded packages:
-nodeand-commonsuffix packages are embedded
For custom dependency handling, use flags:
# Mark a @backstage package as NOT shared (bundle it)
npx @red-hat-developer-hub/cli@latest plugin export \
--shared-package '!/@backstage/plugin-notifications/'
# Embed a specific package
npx @red-hat-developer-hub/cli@latest plugin export \
--embed-package @my-org/common-utils
See references/export-guide.md for detailed export options.
Step 6: Package as OCI Image
Package the dynamic plugin as an OCI container image for distribution:
cd plugins/<plugin-id>-backend
npx @red-hat-developer-hub/cli@latest plugin package \
--tag quay.io/<namespace>/<plugin-name>:v0.1.0
Push the image to your container registry:
podman push quay.io/<namespace>/<plugin-name>:v0.1.0
# or
docker push quay.io/<namespace>/<plugin-name>:v0.1.0
See references/packaging-guide.md for alternative packaging methods (tgz, npm).
Step 7: Configure for RHDH
Create the dynamic plugin configuration for RHDH. Add to dynamic-plugins.yaml:
plugins:
- package: oci://quay.io/<namespace>/<plugin-name>:v0.1.0!<plugin-id>-backend-dynamic
disabled: false
pluginConfig:
# Plugin-specific configuration (optional)
myPlugin:
someOption: value
For local development/testing, copy dist-dynamic to RHDH’s dynamic-plugins-root:
cp -r dist-dynamic /path/to/rhdh/dynamic-plugins-root/<plugin-id>-backend-dynamic
See examples/dynamic-plugins.yaml for a complete configuration example.
Debugging
For local debugging of dynamic plugins:
- Build and copy plugin to
dynamic-plugins-root/ - Start RHDH backend with debugging:
yarn workspace backend start --inspect - Attach IDE debugger to port 9229
- Set breakpoints in
dynamic-plugins-root/<plugin-id>/files
See references/debugging.md for container-based debugging.
Common Issues
Plugin Not Loading
- Verify plugin uses new backend system (
createBackendPlugin) - Check plugin is exported as default export
- Ensure version compatibility with target RHDH
Dependency Conflicts
- Use
--shared-packageto exclude problematic shared deps - Use
--embed-packageto bundle required deps
Build Failures
- Run
yarn tscto check TypeScript errors before export - Ensure all
@backstage/*versions match target RHDH
Additional Resources
Reference Files
For detailed documentation, consult:
references/versions.md– Complete version compatibility matrixreferences/export-guide.md– Detailed export options and flagsreferences/packaging-guide.md– OCI, tgz, and npm packagingreferences/debugging.md– Local and container debugging
Example Files
Examples in examples/:
dynamic-plugins.yaml– Example RHDH plugin configuration