Technology8 min read

Migrate your custom plug-ins to Red Hat Developer Hub 2.1

By · Published by Everything Blog

In short

Upcoming Red Hat Developer Hub release 2.1 introduces major performance and architectural updates, including upstream Backstage's new front-end system and standalone OCI plugin images. Two architectural shifts require preparation before upgrading: adopting the new front-end system and migrating plug-ins to standalone OCI images. Red Hat Developer Hub 2.1 includes other breaking changes not covered here; the upcoming release notes and migration documentation provide a complete list.

Key points

  • Upcoming Red Hat Developer Hub release 2.1 introduces major performance and architectural…: Upcoming Red Hat Developer Hub release 2.1 introduces major performance and architectural updates, including upstream Backstage's new front-end system and standalone OCI plugin images.
  • Two architectural shifts require preparation before upgrading: adopting the new front-end…: Two architectural shifts require preparation before upgrading: adopting the new front-end system and migrating plug-ins to standalone OCI images.
  • Red Hat Developer Hub 2.1 includes other breaking changes not covered here; the upcoming…: Red Hat Developer Hub 2.1 includes other breaking changes not covered here; the upcoming release notes and migration documentation provide a complete list.

Sources checked by our analysis pipeline: 1

Upgrading your internal developer platform shouldn't feel like navigating a minefield. Upcoming Red Hat Developer Hub release 2.1 introduces major performance and architectural updates—including upstream Backstage's new front-end system and standalone OCI plugin images—but getting there requires rethinking how your custom plug-ins are built and mounted.

Two architectural shifts require preparation before upgrading: adopting the new front-end system and migrating plug-ins to standalone OCI images. Red Hat Developer Hub 2.1 includes other breaking changes not covered here; the upcoming release notes and migration documentation provide a complete list.

Important

Update custom front-end plug-ins and dynamic configurations before upgrading to Red Hat Developer Hub 2.1. Older plug-ins that rely on Scalprum mount points cannot load in the 2.1 application shell and will cause the deployment to fail on startup.

Whether you are a platform administrator managing Helm values and Operator configurations or a plugin author maintaining TypeScript blueprints, this guide covers what changed, how configuration maps to the new extension model, and how to test your setup with early 2.1 builds.

The new front-end system: Why you must update plug-ins first

In Red Hat Developer Hub 1.10, you could switch an instance between the old front-end system (packages/app

) and the new front-end system (packages/app-next

) using environment flags:

APP_CONFIG_app_packageName=app-next

ENABLE_STANDARD_MODULE_FEDERATION=true

That toggle lets teams test their plug-ins against the new system while keeping the default setup intact.

In Red Hat Developer Hub 2.1, the previous front-end system and Scalprum—the module federation framework used to dynamically inject plug-ins at runtime—have been removed. packages/app-next

is now the default packages/app

shell. lugins that rely on dynamic Scalprum mount points (dynamicPlugins.frontend

) will fail to mount in the browser.

Removing the old front-end system eliminates roughly 40,000 lines of legacy code, cuts image sizes, and aligns Red Hat Developer Hub directly with upstream Backstage extension blueprints.

Recommended custom plugin migration workflow (plugin authors)

When migrating custom plug-ins, the Red Hat Developer Hub engineering team follows this 6-step process:

- Discover: Check

package.json

,src/plugin.ts

, routes, API factories, components, and current dynamic plugin mount points to catalog what the plug-in exports. - Choose the alpha export: Use an

./alpha

export so the plug-in supports the new front-end system while keeping its root export (.

) working for 1.10 instances. - Migrate extensions: Convert React components to Backstage extension blueprints (

PageBlueprint

,EntityCardBlueprint

,EntityContentBlueprint

). - Update

package.json

: Add the./alpha

export map alongside the root export. - Update local dev wiring: Add a new front-end system dev app entry point (

dev/index.tsx

ordev/nfs.tsx

) using@backstage/frontend-defaults

to test the plug-in locally. - Verify: Run

yarn tsc

from your workspace root and run a build to check types and exports.

What changed for plugin authors

In the old front-end system (in Red Hat Developer Hub version 1.10 and earlier), plug-ins exported standard React components (PluginRoot

), and platform engineers wired those components into UI slots using YAML mount points.

In the new front-end system (in Red Hat Developer Hub 1.10 onwards), plug-ins define their own placement in code through extension blueprints:

// src/alpha.tsx — entry point for the new frontend system

import { createFrontendPlugin, PageBlueprint } from '@backstage/frontend-plugin-api';

import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha';

import { rootRouteRef } from './routes';

const myPage = PageBlueprint.make({

params: {

path: '/my-tools',

routeRef: rootRouteRef,

title: 'My Developer Tools',

loader: () => import('./components/MyToolsPage').then(m => <m.MyToolsPage />),

},

});

const myEntityCard = EntityCardBlueprint.make({

name: 'service-status',

params: {

filter: { kind: 'component' },

loader: () => import('./components/StatusCard').then(m => <m.StatusCard />),

},

});

export default createFrontendPlugin({

pluginId: 'my-tools',

extensions: [myPage, myEntityCard],

});

The dual-export pattern

To keep your plug-in working in Red Hat Developer Hub 1.10 while preparing it for 2.1, export both entry points in package.json

:

{

"name": "backstage-plugin-my-tools",

"exports": {

".": "./src/index.ts",

"./alpha": "./src/alpha.tsx",

"./package.json": "./package.json"

}

}

Developer Hub 1.10 loads .

, while Developer Hub 2.1 reads ./alpha

.

Backstage dynamic plug-ins: What changed in YAML configuration (platform administrators)

In Red Hat Developer Hub 1.x, configuration files explicitly wired plugin components into layout slots. In the new front-end system, plug-ins provide sensible defaults in code, and administrators use YAML to override or disable those defaults.

Old front-end system (dynamicPlugins.frontend ) | New front-end system (app.* ) |

---|---|

Adopter declares UI placement in YAML (mountPoints , importName ) | Plug-ins declare defaults in code; adopters override using app.extensions |

Route and sidebar defined under dynamicRoutes | Inferred automatically from page:* extensions |

Overview cards configured under entity.page.overview/cards | Configured under entity-card:* extensions |

Cross-plugin links wired using routeBindings | Declared in app.routes.bindings |

Disabling UI: remove YAML block or set enabled: false | Set <extension-id>: false in app.extensions |

Example: Overriding the placement of an entity card

Old syntax (dynamic-plugins.yaml

):

dynamicPlugins:

frontend:

my-company.backstage-plugin-custom:

mountPoints:

- mountPoint: entity.page.overview/cards

importName: CustomOverviewCard

config:

layout:

gridColumn: "1 / span 6"

if:

allOf:

- isKind: component

New syntax in 2.1 (app-config.yaml

or pluginConfig

):

app:

extensions:

- entity-card:custom/overview-card:

config:

filter:

kind: component

type: info

Example: Disabling a default card

To hide a built-in card in Red Hat Developer Hub 2.1:

app:

extensions:

- entity-card:catalog/labels: false

Configuration merging and the app.extensions

array

In Red Hat Developer Hub 1.x, front-end layout was split across several files. Default mount points lived in dynamic-plugins.default.yaml

, wrappers had their own defaults, and administrators added overrides in dynamic-plugins.yaml

and app-config.yaml

. Because dynamicPlugins.frontend

was a map of objects, Backstage merged these files key by key, which made it hard to track where a given card or route came from.

In Red Hat Developer Hub 2.1, app-config.yaml

becomes the sole place to customize the interface. Because plug-ins now define layout defaults directly in TypeScript using extension blueprints, dynamic-plugins.default.yaml

drops front-end layout configuration entirely.

First, plug-ins set their own defaults in TypeScript using extension blueprints. Because routes, cards, and default placement are defined in code, dynamic-plugins.default.yaml

no longer carries front-end layout configuration.

Furthermore, Backstage treats app.extensions

as a YAML array:

app:

extensions:

- entity-card:custom/overview-card:

config:

filter:

kind: component

In Backstage, configuration files merge objects key by key, but arrays are replaced completely. If you define app.extensions

in more than one configuration file, the higher-priority file overwrites the entire array without merging entries by ID.

Because arrays overwrite instead of merging, defining app.extensions

in app-config.yaml

replaces default plugin configurations cleanly without requiring multi-file reconciliation.

Removal of dynamic plugin wrappers

In Red Hat Developer Hub 1.x, dynamic plugin wrappers were packaged directly inside the core Developer Hub container image in the folder ./dynamic-plugins/dist/

. Because these wrappers lived inside the main binary container image, they were tied to the Red Hat Developer Hub release cycle. Patching a plugin bug usually meant waiting for a platform patch release or building a custom container image yourself.

In Red Hat Developer Hub 2.1, all wrappers have been removed from the Developer Hub container image (see RHIDP-10858 and PR #5299). Plug-ins are now published as independent, standalone OCI container images built through Red Hat Konflux pipelines and available on quay.io.

Migration skills for coding agents

To help migrate plugins and configuration files, the Developer Hub team has created 2 assistant skills:

The plugin migration skill (rhdh-plugin-nfs-migration)

Available in the rhdh-skills repository, this skill walks an AI agent through the 6-step plugin migration:

- Inspects

package.json

, routes, and components. - Generates extension blueprints (

PageBlueprint

,EntityCardBlueprint

,EntityContentBlueprint

). - Sets up the

./alpha

export map. - Adds a dev app harness and runs TypeScript verification.

Community note: We developed this skill to automate migrating Red Hat’s internal plugin catalog and wanted to share the tooling with the community. While it is an experimental community utility rather than a commercially supported Red Hat feature, it can significantly accelerate your custom plugin refactoring.

The configuration upgrade helper (rhdh-upgrade-helper)

Available in the rhdh-users-skill-pack repository, this skill inspects Helm values, app-config.yaml

, and dynamic-plugins.yaml

files:

- Flags old

./dynamic-plugins/dist/

wrapper paths. - Finds and removes unsupported

!plugin-path

suffixes. - Converts legacy

dynamicPlugins.frontend

mount points intoapp.extensions

blocks.

Testing migrations locally

You can test migrated plug-ins and configuration locally before deploying them to a cluster using RHDH Local.

The main

branch of rhdh-local

runs Red Hat Developer Hub 1.10 (quay.io/rhdh-community/rhdh:1.10

). To test against 2.1 development builds, check out the release-2.1

branch, where compose.yaml

uses RHDH_IMAGE=quay.io/rhdh-community/rhdh:next

:

git clone https://github.com/redhat-developer/rhdh-local.git

cd rhdh-local

git checkout release-2.1

podman compose up -d

Once started, point rhdh-local

at your updated dynamic-plugins.yaml

and verify that your plug-ins load properly.

Migration checklist

Before upgrading an environment to Red Hat Developer Hub 2.1:

- Custom front-end plug-ins implement

createFrontendPlugin

and export using./alpha

. - Plugin

package.json

files export both.

and./alpha

so they work across versions. - Convert

dynamicPlugins.frontend

configuration blocks toapp.extensions

andapp.routes.bindings

. - Remove all

./dynamic-plugins/dist/

wrapper paths fromdynamic-plugins.yaml

. - Catalog plug-ins use the

ref://

reference syntax. APP_CONFIG_app_packageName

andENABLE_STANDARD_MODULE_FEDERATION

are removed from deployment templates.- Catalog index image references are updated to 2.1.

- A test deployment boots cleanly in staging or locally with

rhdh-local

on therelease-2.1

branch.

What's next

Ready to build your internal developer portal? Explore Red Hat Developer Hub and start a no-cost, 60-day trial. To see how the architecture works, review the upstream Backstage front-end system documentation.

Original source: developers.redhat.com

Technology