export-and-package
Purpose
Export and package Backstage plugins as RHDH dynamic plugins for deployment. This skill covers the build, export, and packaging workflow that transforms a developed plugin into a deployable artifact (OCI image, tgz archive, or npm package).
Note: This skill is for exporting and packaging already-implemented plugins. For creating new plugins, use the backend or frontend plugin creation skills first.
When to Use
Use this skill when you need to:
- Export a plugin as a dynamic plugin package
- Package a plugin as an OCI container image
- Create a tgz archive for HTTP distribution
- Publish a plugin to a container registry
- Bundle multiple plugins into a single image
- Generate integrity hashes for package verification
- Troubleshoot export or packaging issues
Prerequisites
Before starting, ensure:
- Plugin is built and compiles without errors (
yarn build) - Container runtime installed (
podmanordocker) - Access to a container registry (e.g., quay.io) if publishing OCI images
- For backend plugins: Uses new backend system with default export
- For frontend plugins: Has valid Scalprum configuration (auto-generated if not present)
Workflow Overview
For the common case, use the automation script:
python scripts/export-plugin.py --plugin-dir plugins/my-plugin \
--tag quay.io/ns/my-plugin:v0.1.0 --push --clean
Run python scripts/export-plugin.py --help for all options (--format tgz, --shared-package, --embed-package, --json).
The steps below explain each phase for advanced use cases (custom shared deps, multi-plugin bundles, npm publishing).
- Build Plugin - Compile TypeScript and verify no errors
- Export as Dynamic Plugin - Create
dist-dynamic/with RHDH CLI - Package as Artifact - Create OCI image, tgz, or npm package
- Push to Registry - Publish to container or npm registry
- Verify Locally - Test before deployment (optional)
Step 1: Build Plugin
Before exporting, ensure the plugin builds successfully:
cd plugins/<plugin-id> # or plugins/<plugin-id>-backend
yarn build
yarn tsc # Verify no TypeScript errors
Step 2: Export as Dynamic Plugin
Run the RHDH CLI export command from the plugin directory:
npx @red-hat-developer-hub/cli@latest plugin export
This creates a dist-dynamic/ directory containing:
- Compiled JavaScript optimized for dynamic loading
- Modified
package.jsonwith peer/bundled dependencies - Config schema (if defined)
- For frontend:
dist-scalprum/with webpack federated modules
Export Options
Control Shared Dependencies
By default, all @backstage/* packages are shared (provided by RHDH at runtime). Override this behavior:
# 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-utils
Embed Packages
Embed workspace or third-party packages into the plugin:
npx @red-hat-developer-hub/cli@latest plugin export \
--embed-package @my-org/plugin-common \
--embed-package @my-org/utils
Combined Example
npx @red-hat-developer-hub/cli@latest plugin export \
--shared-package '!/@backstage/plugin-notifications/' \
--embed-package @internal/common-utils
See references/export-options.md for all available options.
Step 3: Package as Artifact
Choose a packaging format based on your deployment needs.
OCI Image (Recommended for Production)
Create a container image:
npx @red-hat-developer-hub/cli@latest plugin package \
--tag quay.io/<namespace>/<plugin-name>:v0.1.0
Specify container tool if needed:
npx @red-hat-developer-hub/cli@latest plugin package \
--container-tool docker \
--tag quay.io/<namespace>/<plugin-name>:v0.1.0
Available tools: podman (default), docker, buildah
tgz Archive
Create a tar archive for HTTP distribution:
cd dist-dynamic
npm pack
Get the integrity hash:
npm pack --json | jq -r '.[0].integrity'
npm Package
Publish to a private npm registry:
cd dist-dynamic
npm publish --registry https://your-private-registry.com
Multi-Plugin Image
Bundle frontend and backend plugins in one image:
# 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 together from monorepo root
cd ../..
npx @red-hat-developer-hub/cli@latest plugin package \
--tag quay.io/<namespace>/my-plugin-bundle:v0.1.0
See references/packaging-formats.md for detailed format comparison.
Step 4: Push to Registry
OCI Image
# Podman
podman push quay.io/<namespace>/<plugin-name>:v0.1.0
# Docker
docker push quay.io/<namespace>/<plugin-name>:v0.1.0
Private Registry Authentication
Set the auth file environment variable:
export REGISTRY_AUTH_FILE=~/.config/containers/auth.json
# or
export REGISTRY_AUTH_FILE=~/.docker/config.json
Image Digest
After pushing, get the digest for reproducible deployments:
podman inspect --format='{{.Digest}}' quay.io/<namespace>/<plugin-name>:v0.1.0
Use digest in dynamic-plugins.yaml:
plugins:
- package: oci://quay.io/<namespace>/<plugin-name>@sha256:abc123...!<plugin-id>-dynamic
disabled: false
Step 5: Verify Locally (Optional)
Test the exported plugin before publishing:
# Copy to local RHDH instance
cp -r dist-dynamic /path/to/rhdh/dynamic-plugins-root/<plugin-id>-dynamic
# Start RHDH and verify plugin loads
yarn workspace backend start
Check logs for:
loaded dynamic backend plugin- SuccessSkipping disabled dynamic plugin- Plugin disabled in config- Error messages during initialization
Configuration Examples
Backend Plugin
plugins:
- package: oci://quay.io/<namespace>/<plugin-name>:v0.1.0!<plugin-id>-backend-dynamic
disabled: false
pluginConfig:
myPlugin:
apiUrl: https://api.example.com
Frontend Plugin
plugins:
- 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: MyPage
Multi-Plugin Bundle
plugins:
# Frontend from bundle
- package: oci://quay.io/<namespace>/my-bundle:v0.1.0!my-plugin
disabled: false
pluginConfig:
dynamicPlugins:
frontend:
my-org.plugin-my-plugin:
mountPoints:
- mountPoint: entity.page.overview/cards
importName: MyCard
# Backend from same bundle
- package: oci://quay.io/<namespace>/my-bundle:v0.1.0!my-plugin-backend-dynamic
disabled: false
See examples/dynamic-plugins.yaml for complete examples.
Troubleshooting
Export Fails
Missing dependencies:
yarn add -D <missing-package>
npx @red-hat-developer-hub/cli@latest plugin export
TypeScript errors:
yarn tsc
# Fix errors, then retry export
Clear stale artifacts:
rm -rf dist dist-dynamic
yarn build
npx @red-hat-developer-hub/cli@latest plugin export
Package Fails
Container tool not found:
# Specify available tool
npx @red-hat-developer-hub/cli@latest plugin package \
--container-tool docker \
--tag quay.io/<namespace>/<plugin-name>:v0.1.0
Permission denied:
# Check registry login
podman login quay.io
Plugin Not Loading in RHDH
- Verify package path matches plugin ID
- Check version compatibility with target RHDH
- Ensure default export exists (backend plugins)
- Verify Scalprum name matches (frontend plugins)
- Check RHDH logs for specific errors
Integrity Hash Mismatch
Regenerate the hash:
cd dist-dynamic
npm pack --json | jq -r '.[0].integrity'
Update dynamic-plugins.yaml with new hash.
Reference Files
references/export-options.md- All export CLI optionsreferences/packaging-formats.md- Format comparison and best practicesreferences/integrity-hashes.md- Hash generation and verification
Example Files
examples/dynamic-plugins.yaml- Complete configuration examples
More from redhat-developer/rhdh-skill
rhdh-jira
|
9skill-maker
Create new agent skills or consolidate existing skills following the Agent Skills open standard (agentskills.io). Interviews the user relentlessly about intent, scope, and edge cases before drafting. Covers SKILL.md structure, frontmatter, progressive disclosure, description optimization, script bundling, sub-command architecture, setup gates, context systems, and review. Use when the user wants to create a skill, write a skill, build a new skill, make a skill, draft a SKILL.md, or mentions "skill-maker". Also use when asked to package expertise, workflows, or domain knowledge into a reusable skill. Also use when asked to consolidate skills, merge skills, combine skills, reduce skill count, or refactor multiple skills into one.
7create-skill
Create new agent skills following the Agent Skills open standard (agentskills.io). Interviews the user relentlessly about intent, scope, and edge cases before drafting. Covers SKILL.md structure, frontmatter, progressive disclosure, description optimization, script bundling, and review. Use when the user wants to create a skill, write a skill, build a new skill, make a skill, draft a SKILL.md, or mentions "create-skill". Also use when asked to package expertise, workflows, or domain knowledge into a reusable skill.
5rhdh
Handles all RHDH-related work — "RHDH", "Red Hat Developer Hub", or "Developer Hub". Primary entry point for plugin development, overlay management, environment setup, repo navigation, version compatibility, CI/CD, configuration, debugging, and general RHDH ecosystem knowledge. Routes to specialized sub-skills as needed.
3overlay
Manages the rhdh-plugin-export-overlays repository — onboards plugins to the Extensions Catalog, updates plugin versions, fixes overlay build failures, triages and analyzes PRs, triggers publishes, and manages plugin workspaces. Use when working with overlays, importing plugins, debugging CI, checking PRs, or bumping versions.
3rhdh-local
Skill for testing RHDH plugins locally using the rhdh-local-setup customization system. Covers enabling/disabling plugins, switching modes, running end-to-end plugin tests, starting/stopping RHDH (up/down), health checks, troubleshooting errors (504, startup failures), and backup/restore of configurations.
3