Export and package Backstage plugins as RHDH dynamic plugins for deployment. Transforms a developed plugin into a deployable artifact (OCI image, tgz archive, or npm package).
- Export a plugin as a dynamic plugin package
- Package as OCI container image, tgz archive, or npm package
- Publish to a container or npm registry
- Bundle multiple plugins into a single image
- Generate integrity hashes for package verification
- Plugin builds without errors (
yarn build) - Container runtime (
podman,docker, orbuildah) for OCI images - Registry access (e.g., quay.io) for publishing
- Backend plugins: new backend system with default export
- Frontend plugins: valid Scalprum configuration (auto-generated if absent)
Use the automation script for the common case:
python scripts/export-plugin.py --plugin-dir plugins/my-plugin \
--tag quay.io/ns/my-plugin:v0.1.0 --push --cleanRun python scripts/export-plugin.py --help for all options.
cd plugins/<plugin-id> # or plugins/<plugin-id>-backend
yarn build
yarn tsc # Verify no TypeScript errorsnpx @red-hat-developer-hub/cli@latest plugin exportCreates dist-dynamic/ with compiled JavaScript optimized for dynamic loading.
# Bundle a @backstage package instead of sharing
npx @red-hat-developer-hub/cli@latest plugin export \
--shared-package '!/@backstage/plugin-notifications/'
# Mark a non-backstage package as shared
npx @red-hat-developer-hub/cli@latest plugin export \
--shared-package @my-org/shared-utilsnpx @red-hat-developer-hub/cli@latest plugin export \
--embed-package @my-org/plugin-common \
--embed-package @my-org/utilsRead export-options.md (in this directory) for all available options.
npx @red-hat-developer-hub/cli@latest plugin package \
--tag quay.io/<namespace>/<plugin-name>:v0.1.0Specify container tool if needed:
npx @red-hat-developer-hub/cli@latest plugin package \
--container-tool docker \
--tag quay.io/<namespace>/<plugin-name>:v0.1.0cd dist-dynamic
npm pack
npm pack --json | jq -r '.[0].integrity' # Get integrity hashcd dist-dynamic
npm publish --registry https://your-private-registry.com# Export both plugins first
cd plugins/my-plugin && npx @red-hat-developer-hub/cli@latest plugin export
cd ../my-plugin-backend && npx @red-hat-developer-hub/cli@latest plugin export
# Package from monorepo root
cd ../..
npx @red-hat-developer-hub/cli@latest plugin package \
--tag quay.io/<namespace>/my-plugin-bundle:v0.1.0Read packaging-formats.md (in this directory) for detailed format comparison.
# Podman
podman push quay.io/<namespace>/<plugin-name>:v0.1.0
# Docker
docker push quay.io/<namespace>/<plugin-name>:v0.1.0Get the digest for reproducible deployments:
podman inspect --format='{{.Digest}}' quay.io/<namespace>/<plugin-name>:v0.1.0cp -r dist-dynamic /path/to/rhdh/dynamic-plugins-root/<plugin-id>-dynamic
yarn workspace backend startCheck logs for loaded dynamic backend plugin (success) or error messages.
plugins:
- package: oci://quay.io/<namespace>/<plugin-name>:v0.1.0!<plugin-id>-backend-dynamic
disabled: false
pluginConfig:
myPlugin:
apiUrl: https://api.example.complugins:
- package: oci://quay.io/<namespace>/<plugin-name>:v0.1.0!<plugin-id>
disabled: false
pluginConfig:
dynamicPlugins:
frontend:
my-org.plugin-my-plugin:
dynamicRoutes:
- path: /my-plugin
importName: MyPageplugins:
- package: oci://quay.io/<namespace>/my-bundle:v0.1.0!my-plugin
disabled: false
- package: oci://quay.io/<namespace>/my-bundle:v0.1.0!my-plugin-backend-dynamic
disabled: falseSee examples/dynamic-plugins.yaml for complete examples.
- Missing deps:
yarn add -D <missing-package> - TypeScript errors:
yarn tscthen fix - Stale artifacts:
rm -rf dist dist-dynamic && yarn build
- Container tool not found: use
--container-tool docker - Permission denied:
podman login quay.io
- Verify package path matches plugin ID
- Check version compatibility with target RHDH
- Ensure default export exists (backend plugins)
- Verify Scalprum name matches (frontend plugins)
Regenerate: cd dist-dynamic && npm pack --json | jq -r '.[0].integrity'
Read integrity-hashes.md (in this directory) for complete hash reference.