Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • See all Red Hat products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Red Hat OpenShift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • See all technologies
    • Programming languages & frameworks

      • Java
      • Python
      • JavaScript
    • System design & architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer experience

      • Productivity
      • Tools
      • GitOps
    • Automated data processing

      • AI/ML
      • Data science
      • Apache Kafka on Kubernetes
    • Platform engineering

      • DevOps
      • DevSecOps
      • Red Hat Ansible Automation Platform for applications and services
    • Secure development & architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & cloud native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • See all learning resources

    E-books

    • GitOps cookbook
    • Podman in action
    • Kubernetes operators
    • The path to GitOps
    • See all e-books

    Cheat sheets

    • Linux commands
    • Bash commands
    • Git
    • systemd commands
    • See all cheat sheets

    Documentation

    • Product documentation
    • API catalog
    • Legacy documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore the Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Introducing the Dynamic Plug-ins Factory for Developer Hub

January 15, 2026
Evan Shortiss
Related topics:
Developer ToolsPlatform engineering
Related products:
Red Hat Advanced Developer SuiteRed Hat Developer Hub

    In my previous article, I demonstrated how to manually build and package a Backstage plug-in to make it compatible with the dynamic plug-in system in Red Hat Developer Hub. That approach gives you total control. However, it requires developer expertise and a deep understanding of Backstage and the JavaScript ecosystem. You also need Node.js and Yarn installed locally to manage dependencies, run build commands, and manually push images.

    But what if you aren't developing the plug-in? What if you are a platform engineer who simply needs to assemble a set of Backstage plug-ins and keep them updated without maintaining a dozen Git forks or a complex build environment? This article explains how the Dynamic Plug-in Factory can help.

    The assembly line approach

    The Dynamic Plug-in Factory is an experimental Developer Preview tool from the Red Hat team that shifts the plug-in build process from an imperative approach to a declarative one. Instead of running a sequence of commands, you define build parameters with configuration files.

    The plug-in factory reduces the complexity of the build process by encapsulating many of the developer tools within a container image. When you feed it a configuration, it produces ready-to-deploy plug-in artifacts. This ensures plug-ins are built in a clean, reproducible environment every time, regardless of what version of the Backstage dependencies you have in your local development or continuous integration (CI) environments.

    Let’s revisit the entity feedback plug-in from the previous article, but this time I’ll demonstrate how to build it using the factory approach.

    Prerequisites

    Unlike the manual method, you do not need Node.js, Yarn, or the RHDH CLI installed. You only need a container engine like Podman or Docker installed in your environment. To get started with Podman, you can use Podman Desktop, or install the Podman CLI directly using a package manager.

    Once you have installed a container engine, pull the Developer Hub 1.8 compatible version of the dynamic plugin factory image. The plug-in built in this article targets Developer Hub v1.8.0 and Backstage v1.42.5 as a result.

    podman pull quay.io/rhdh-community/dynamic-plugins-factory:1.8

    Step 1: Create a configuration

    This part is easy. Simply create a folder on your machine. For example, I created a folder named my-plugins. Inside this folder, create a config subfolder. Additionally, create a .gitignore to make sure you don’t commit any secrets by mistake.

    mkdir -p my-plugins/config
    cd my-plugins
    echo ".env" >> .gitignore

    Step 1: Define the source

    The factory operates on one repository at a time. You define this upstream source in a config/source.json file. The repo-ref is pointing to a specific commit that bumps the Entity Feedback plug-in version to support Backstage 1.42.3 close to Developer Hub 1.8’s Backstage version of 1.42.5.

    {
      "repo": "https://github.com/backstage/community-plugins",
      "repo-ref": "2b60b5959e821b216f9c8fb224caf9fc8d51f075" 
    }

    Pro tip: The source.json only accepts a single repo. You can build multiple workspaces from a single repository. To build plug-ins from different repositories (e.g., the Backstage Community plug-ins repository and a private internal repository), you will need to create separate config folders for each upstream and run the factory for each config. 

    Step 2: Specify the target plug-ins

    The community repository contains dozens of plug-ins. Create a plugins-list.yaml to specify exactly which packages should be built and published as dynamic plug-ins:

    plugins/entity-feedback:
    plugins/entity-feedback-backend: --embed-package @backstage/plugin-notifications-node --embed-package @backstage/plugin-notifications-common

    The paths in this file specifically reference the plug-in paths for the targeted plug-in workspace. In this case, the workspace path is workspaces/entity-feedback and the subfolders to build plug-ins are those listed in the plugins-list.yaml.

    You can add more arguments to each entry in this file. For example, certain plug-ins specify other plug-ins as dependencies. Use the --embed-package argument to ensure these dependencies are met. 

    In the case of the Entity Feedback backend, embed these two packages (other plug-ins): 

    • @backstage/plugin-notifications-node
    • @backstage/plugin-notifications-common 

    Failure to specify these embedded packages would result in MODULE_NOT_FOUND errors when Developer Hub attempts to load the entity-feedback-backend plug-in.

    If you notice MODULE_NOT_FOUND errors when loading a dynamic plug-in you’ve packaged, that's a strong indication you need to embed the specified module or the pre-installed plug-in in Developer Hub. 

    Note

    Node.js uses the term “module” to refer to libraries. In Backstage, plug-ins are distributed as Node.js modules. Broadly speaking, “packages” is a runtime agnostic term and is therefore used by the factory.

    Step 3: Configure the registry (.env)

    In the manual method, you had to run podman login and podman push for every plug-in. The factory automates this process.

    Create a .env file in the config directory. This file tells the factory where to push the resulting container images.

    # Registry Configuration
    REGISTRY_URL=quay.io
    REGISTRY_NAMESPACE=your-namespace # usually this is your username or org name
    REGISTRY_USERNAME=your-quay-or-robot-username
    REGISTRY_PASSWORD=your-quay-or-robot-password

    Note, I’m using a robot account with specific write permissions instead of passing my Quay username and password directly to the factory container. Other container registries support similar capabilities. Using a robot account is optional, but recommended when build systems will access Quay.io on your behalf. 

    Configure repositories and a robot account

    To configure a robot account, first create the image repositories your factory will push the plug-ins to. In this case, those are named backstage-community-plugin-entity-feedback and backstage-community-plugin-entity-feedback-backend.

    Figure 1 shows an example of creating an empty repository on Quay.io with the correct name.

    A screenshot showing how to create an empty repository on Quay.io
    Figure 1: Creating an empty repository on Quay.io.

    Next, go to your Account Settings and select Robot Accounts. Create a new robot account, or reuse an existing one, then assign it write permissions for your two new repositories. This is shown in Figure 2.

    Screenshot showing how to set Quay Robot Account permissions
    Figure 2: Setting Quay robot account permissions to include write access.

    Lastly, obtain the robot account username and password by clicking on it in the Robot Accounts listing, as shown in Figure 3.

    Obtaining a Quay Robot Account password
    Figure 3: Obtaining a Quay robot account password.

    Step 4: Run the factory

    This is where automation takes over. No need to run yarn install or tsc. Simply run the factory container, mounting the config directory and specifying the target workspace.

    Note that we are adding the --push-images flag to tell the factory to push the images to the container registry specified in the .env configuration.

    podman run --rm -it \
      --device /dev/fuse \
      -v ./config:/config \
      quay.io/rhdh-community/dynamic-plugins-factory:1.8 \
      --push-images \
      --workspace-path=workspaces/entity-feedback

    The container will:

    1. Clone the repository defined in source.json.
    2. Install all necessary dependencies in an isolated environment.
    3. Build the plug-ins listed in plugins-list.yaml.
    4. Package them and automatically push them to Quay.io.

    Once the build is complete, make sure that the new container image repositories are public to avoid the need to configure pull secrets to follow this article. Figure 4 shows where the repository visibility setting is located in Quay.io. 

    Setting the Quay repository visibility to public in the web UI
    Figure 4: Setting the Quay repository visibility to public.

    Step 5: Add the plug-ins to Developer Hub

    Once the factory has successfully pushed your images to Quay.io, the process for adding them to your Red Hat Developer Hub instance is identical to the manual method.

    You will need to update your dynamic-plugins.yaml configuration to point to the new OCI images you just created.

    Note

    For a detailed explanation of the pluginConfig and mountPoints for this specific plug-in, refer to the "Add the plug-ins to Developer Hub" section in my previous article and the official documentation for frontend plug-ins.

    plugins:
      - package: oci://quay.io/evanshortiss/backstage-community-plugin-entity-feedback:0.9.0!backstage-community-plugin-entity-feedback
        disabled: false
        pluginConfig:
          dynamicPlugins:
            frontend:
              backstage-community.plugin-entity-feedback:
                entityTabs:
                  - mountPoint: entity.page.feedback
                    path: /feedback
                    title: Feedback
                mountPoints:
                  - config:
                      layout:
                        gridColumn: 1 / -1
                    importName: StarredRatingButtons
                    mountPoint: entity.page.feedback/cards
                  - config:
                      layout:
                        gridColumn: 1 / -1
                    importName: EntityFeedbackResponseContent
                    mountPoint: entity.page.feedback/cards
    
      - package: oci://quay.io/evanshortiss/backstage-community-plugin-entity-feedback-backend:0.11.0!backstage-community-plugin-entity-feedback-backend
        disabled: false

    Once the plug-ins are added to your configuration, restart Developer Hub and confirm they’ve been installed by viewing the container logs and viewing the Installed packages section in the Admin > Extensions view, as shown in Figure 5.

    Viewing the Entity Feedback Plugins in Red Hat Developer Hub's plugin list
    Figure 5: Viewing the Entity Feedback Plug-ins in Red Hat Developer Hub's plug-in list.

    Customizing patches, overlays, and forks

    The factory allows you to apply patch files and overlays to the source code before building. If you need to change a single CSS color or a hardcoded URL, a patch file is a quick mechanism that avoids the need to maintain a permanent fork of the repository. You can use overlays to replace entire files instead of specific parts of a file. However, if you are making significant changes, such as rewriting logic or adding features, writing patches, or overlays could become tedious. In those cases, maintaining a fork might be a better alternative. 

    Wrap up

    If you are a plug-in developer, you may prefer your own process. If you are a platform engineer tasked with curating a catalog of many different open-source plug-ins for your internal developer portal, the Dynamic Plugin Factory offers a cleaner, more scalable way to manage your supply chain.

    Visit the Dynamic Plug-in Factory on GitHub. We welcome your contributions!

    Related Posts

    • Red Hat Developer Hub: The fastest path to Backstage on Kubernetes

    • Backstage authentication and catalog providers: A practical guide

    • How to build your dynamic plug-ins for Developer Hub

    • MCP in Red Hat Developer Hub: Chat with your catalog

    Recent Posts

    • A deep dive into OpenShift Container Platform 4.20 performance

    • Introducing the Dynamic Plug-ins Factory for Developer Hub

    • Diagnose Java applications using Cryostat 4.1

    • AI-driven vulnerability management with Red Hat Lightspeed MCP

    • Accelerate multi-turn LLM workloads on OpenShift AI with llm-d intelligent routing

    What’s up next?

    Learning Path Streamline Development: GitHub Integration and Software Templates in Red Hat Developer Hub feature image

    Streamline Development: GitHub Integration and Software Templates in Red Hat...

    In this learning exercise, we’ll build on a freshly installed Red Hat...
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue