Why plugins that moved repositories break Backstage upgrades
An upgrade that stalls on a plugin usually means that plugin no longer ships from the core Backstage repository. You bump the @backstage packages, the install or build fails on a package that cannot be found or resolved, and the plugin's peer dependencies point at a Backstage release your app has already left. Plugins that left the core repository now live in the community-plugins repository, often under new package names, with their own release cadence. Your old dependency line may still exist on the registry, but it no longer tracks the core release line, so it cannot be upgraded by the same steps. Act on this before the version bump if you can, or as the first step of the bump if the failure is already in front of you. Do not assume the bump tool will find the new package for you.
The supported path has two parts, and the order matters. First, move all @backstage core packages together with yarn backstage-cli versions:bump, then apply the template changes the Upgrade Helper shows for your app and backend packages. Second, replace each moved plugin with its new package name, and pin it to a release that matches the Backstage version you just reached. Backstage ships a main release line monthly, on the Tuesday before the third Wednesday, and a next release line weekly on Tuesdays, so a plugin release built for one line may not fit the other. The latest release named in the Backstage GitHub releases page is v1.55.3, with 1.56.0 in the next line. Confirm the compatibility of each plugin against the exact release you target, not the most recent one.
What changes when a plugin moves and what you must do
This table compares each change that typically follows when a plugin leaves the core Backstage repository for the community-plugins repository, with the impact on your app and the action you need to take. Read it row by row against the plugin's changelog and repository before you change any dependency, since the specifics differ from plugin to plugin.
| Change | Impact | Action needed |
|---|---|---|
| New package name and scope | Imports and dependency names in your app or backend change, so the old package no longer resolves after an update | Find the new package name in the plugin's README or changelog, then update package.json and every import path |
| Release cadence differs from core | The plugin may ship on its own schedule, not with the monthly main line or weekly next line | Confirm the plugin's release history and pin a version known to work with your Backstage release |
| Maintenance status and ownership | The plugin may have a different maintainer, slower fixes or reduced support compared with core packages | Check recent commits, open issues and maintainer activity before you rely on it for production |
| Peer dependency ranges against @backstage packages | Installing the plugin may fail or warn if its supported @backstage range excludes your current core version | Compare the plugin's peer ranges with your versions:bump target and move both together |
| Configuration keys and import paths | Keys in app-config files or plugin registration code may move, be renamed or be removed | Read the plugin's setup guide for your release and update app-config.yaml and wiring code to match |
| Old package removed from the lockfile | A stale old package can leave duplicate or conflicting dependencies in yarn.lock | Remove the old package, reinstall, and confirm the lockfile contains only the new package name |
How the Backstage versioning policy shapes version pins
The Backstage versioning policy determines how far a community plugin can drift from your core version, so pin decisions start there. The main release line ships monthly, on the Tuesday before the third Wednesday of each month, and the next release line ships weekly on Tuesdays. A community plugin maintained on its own cadence may not track either line, so a release that matched your @backstage packages last month can fall behind this month. Before you choose a plugin version, compare the Backstage release your app runs against the plugin's declared peer dependencies, and confirm the plugin's compatibility notes for that exact core version rather than assuming the latest plugin release fits.
Security backports set how old a pin you can safely hold. The versioning policy says high and critical severity vulnerabilities will always be backported to Backstage releases from the last 6 months where feasible, and other security fixes may be backported. Those guarantees apply to core releases, not to community plugins, so a plugin pinned to a release that predates your core upgrade may carry issues the core line no longer patches. Treat each pin as a dated decision: record the core version it was tested against, and plan to move the plugin forward within the window in which the core line still receives backports. Confirm with the plugin maintainers whether they backport fixes at all.
Node.js support is a second constraint that plugins must respect. Backstage supports exactly two adjacent even-numbered Node.js releases, and as of Backstage 1.46.0 these are Node.js 22 and 24, according to the versioning policy. A plugin release that declares or relies on a runtime outside that window can break your build even when its Backstage peer range looks correct. When you pick a plugin version, check its engine declaration and CI results against the Node.js release your app uses, and confirm that the plugin's supported Node.js versions overlap with the two Backstage supports.
Prepare the plugin inventory and test environment before switching
Switching plugins to the community-plugins repository touches dependencies, lockfiles and live data at once. The cards below cover the groundwork that keeps that change reviewable: knowing what you run, judging whether each plugin is still maintained, preserving a known-good state, and proving the change on a copy of production before it reaches users.
Inventory every plugin dependency
List every plugin declared in packages/app and packages/backend, recording the current package name, the installed version and whether it is a frontend or backend module. Search for both the old core package names and any plugin that is already a community package, because a single app often mixes the two. Many plugins also pull in companion packages such as -common or -node modules, so capture those as well. Keep the list in version control so the migration can be reviewed line by line.
Check maintenance status of each plugin
For each inventoried plugin, open its source repository and check recent commits, the date of the last release, whether maintainers respond to issues and how many issues stay open against the current Backstage line. A plugin that has not moved with recent Backstage releases is a risk to schedule, not a switch to make by default. Record a decision for each plugin: migrate, replace, keep as is with a documented exception, or remove. Ask the owning team to confirm who will support each plugin after the move.
Back up lockfile and app configuration
Commit the current yarn.lock and the configuration files, including app-config.yaml and any environment-specific overrides, to a tagged branch before editing dependencies. Restoring the lockfile is the fastest way back if a version resolves unexpectedly. Keep secrets out of the backup and reference them the same way the running system does. Note the exact Git commit that is in production so the rollback target is unambiguous.
Stand up staging on the target release
Build a staging instance on the Backstage release you plan to run, using the same container image build and configuration as production. Point it at a copy of production PostgreSQL rather than an empty database, because plugin schema changes and catalog ingestion only show their real effects against existing data. Restrict the copy's access to authentication, integrations and outbound notifications so test activity cannot reach real systems. Ask your platform team to confirm how the database copy is refreshed and who is allowed to hold it.
How to switch a moved plugin to its new package
This sequence moves a plugin from its old core package to the community-plugins package while keeping every @backstage dependency on one release line. The result is a staged build that passes type checks and tests, and a rollback point if verification fails.
Align core packages with versions bump
Run
yarn backstage-cli versions:bumpfrom the repository root so every @backstage package moves to the same release line before you touch the plugin. The platform engineer running the upgrade commits the resulting lockfile and package changes on a branch of their own. You know this step is done whenyarn installcompletes cleanly and the app still starts locally without the moved plugin changes applied. Record the lockfile commit hash so you have a clean reference point.Read the upgrade helper for template changes
Open the Backstage Upgrade Helper and compare your current release with the target release. Note every template change that touches the app or backend packages where the moved plugin is wired in, including any changes to plugin registration or config keys. The engineer keeps this list in the change ticket. You know this step is done when each affected file in your repository has a matching line item, or a note that no change applies.
Remove the old plugin package
Delete the old plugin dependency from the package.json of each app and backend package that uses it, then run
yarn installso the lockfile drops the old entry. Check whether any other workspace package still depends on the old name, because a stale reference will cause a failure later. You know this step is done when a search of the repository for the old package name returns no dependency entries, only any remaining documentation you have chosen to update.Install the community-plugins package at a matching version
Find the community-plugins package that replaces the old one, and confirm its release notes and peer dependency ranges. Install the version whose peer ranges accept the @backstage packages on your current release line, using
yarn addin the correct workspace. Confirm the package is still maintained by reviewing its recent commits and release history before you commit to it. You know this step is done whenyarn whyshows a single resolved copy of each @backstage core package and the peer warnings are resolved.Update imports and app or backend wiring
Change import paths and export names to match the new package, then update the plugin registration in the frontend app and backend index. Apply any config key renames noted in the upgrade helper or the new package documentation. Keep the diff limited to the moved plugin so reviewers can separate it from the versions bump. You know this step is done when the app and backend both start in a local environment and the plugin route or API responds.
Run type checks and tests
Run
yarn tscat the repository root, then run the unit and integration tests for the frontend and backend packages that use the plugin. Fix type errors that come from changed exports rather than suppressing them. The engineer records the command output in the change ticket. You know this step is done whenyarn tscexits without errors and the test suites for affected packages pass on a clean install.Verify the plugin in staging
Build the container image with the new lockfile, tag it, and deploy it to staging with the same configuration used in production. Exercise the plugin's main views and any backend endpoints it calls, and check the logs for deprecation warnings or missing-module errors. Compare results with the current production behavior for the same entities. You know this step is done when the verification checklist is signed off by the team that owns the plugin and no new errors appear in staging logs.
Promote or roll back
Promote the tagged image to production only after staging passes, and record the previous image tag and lockfile commit before the deployment starts. If the plugin fails verification after promotion, restore the previous lockfile and redeploy the previous image tag, then reopen the change ticket with the failing checks. You know this step is done when production shows the plugin working with the new package, or the rollback has completed and the previous tag is confirmed as running.
Choosing between pinning, forking and replacing a plugin
Pinning keeps the plugin at the last community release that declares a peer range matching your Backstage version. Your team still installs the plugin from its new package name, but it does not take new plugin releases until you choose to move. The upgrade work stays with your team, and it recurs every time you bump the @backstage packages, because the pinned plugin may stop matching your core version.
- Ownership: Your team owns the pin, the version check and the test run after each Backstage bump.
- Recurring work: Each monthly bump needs a check of the plugin's peer dependencies against the new core release.
- Best signal: The community plugin is actively maintained and its latest release still declares a peer range that includes your version.
- Risk: Security fixes and bug fixes in the plugin do not reach you until you unpin, so the pin can quietly age.
- Exit point: Pinning works well as a short bridge, and it becomes a liability when the plugin stops releasing.
Before choosing this path, confirm the plugin's current maintenance status and the peer range of its latest release in the community-plugins repository.
Forking copies the plugin source into your own repository, then your team maintains it as internal code. This gives you control over timing and patches, but it also means you own every change that the upstream plugin would have received. Forks are most useful when the plugin is close to what you need and you can accept ongoing maintenance of a package your organization now owns.
- Ownership: Your team owns the code, the package name, the release process and the security response for the fork.
- Recurring work: You must port upstream fixes you want, resolve conflicts, and keep the fork's dependencies current.
- Best signal: The upstream plugin is unmaintained or stalled, but the code is small enough and well enough tested to own.
- Risk: A fork diverges quickly, and an unowned fork becomes the hardest part of the next upgrade.
- Licensing: Confirm the plugin's license permits modification and redistribution inside your organization before you copy it.
Ask the team that will own the fork to estimate the recurring hours, and agree in writing who responds to security advisories affecting it.
Replacing means removing the moved plugin and meeting the same need with a different integration, a different plugin or a custom plugin built on current Backstage APIs. The upgrade work moves to whoever owns the replacement, and the up-front cost is higher because the design, data mapping and testing start again. This path suits plugins whose functions are narrow, or where the upstream project no longer fits the portal's architecture.
- Ownership: A replacement with another community plugin shifts upkeep to that plugin's maintainers. A custom plugin keeps the upkeep in your team.
- Recurring work: Custom plugins need compatibility checks against each core release, similar to internal plugins.
- Best signal: The feature need is narrow, the plugin is abandoned, or the current plugin depends on APIs that your architecture no longer uses.
- Risk: Users lose familiar behavior during the switch, so plan a parallel run and communicate the change.
- Scope: Separate the replacement decision from the upgrade so the team does not fix two problems at once.
Before committing, confirm which team will own the replacement after launch and whether its maintenance status matches your expected support window.
What makes a plugin move take longer
This table lists the factors that most change how long a community-plugins migration takes and which way each one pushes. Read each row as a question to answer about your own app before estimating the work. The main takeaway is that the number of moved plugins matters less than how tightly they are wired into your app and backend, and how much in-house ownership you have to test and decide.
| Driver | Effect on effort | What to check |
|---|---|---|
| Number of moved plugins | More moved plugins raise effort roughly in step, since each has its own package name, config keys and release cadence to reconcile. | Inventory every plugin in package.json that came from the core repository and note its new package name. |
| Depth of customization in app and backend wiring | Heavily customized wiring (custom entity pages, extended routes, overridden components) increases effort more than the number of plugins does. | Find where plugins are imported in the app and backend packages, and list any local overrides or wrappers. |
| Use of deprecated packages | Apps still using deprecated packages need extra steps to replace them before or during the move, which can stretch the work. | Check which @backstage packages your app and plugins import and compare them against the current upgrade notes. |
| Plugin maintenance status | Plugins with slow or stalled maintenance may need a fork, a pinned old version or a replacement, which adds decisions and testing. | Review each plugin's recent commits, open issues and release history in its community-plugins repository directory. |
| Peer dependency mismatches | Mismatched peer dependencies between the plugin and your Backstage release cause install failures and runtime errors that take time to trace. | Compare each plugin's declared peer dependencies with the @backstage versions your app uses after running versions:bump. |
| Catalog size and database used in staging | A large catalog or a production-sized database makes staging tests slow, so each verification cycle takes longer. | Confirm you have a staging environment with representative catalog data and a database copy you can restore quickly. |
| In-house Backstage ownership | Teams with no one who owns the portal often need outside help to make version and pinning decisions, which adds coordination time. | Name an owner for the plugin dependency decisions and confirm who reviews changes before they reach production. |
Questions teams ask before switching community plugins
How much effort does moving a plugin to the community-plugins repository take?
The effort depends mostly on how far the plugin's package names, imports and configuration changed between the old location and the new one, and on how many @backstage packages your app pins. A plugin that moved with a simple dependency rename and an unchanged API is a small change. A plugin that also changed its frontend or backend wiring, or that depends on deprecated packages, takes more work. Your app's own customizations add to it. Ask any partner to inventory each plugin, its current version, its new package name and the config keys it reads before agreeing on scope.
How long does a plugin move take, and what changes that?
Duration is driven by the number of plugins, how many of them depend on the Backstage release line you run, and how much testing your portal needs before a release. Plugins that share a dependency tree with your core upgrade can be sequenced together, while plugins that need code changes in your own packages take longer because they need review and a test cycle. Release cadence also matters: the main release line ships monthly and the next line ships weekly, so a plugin version that matches one line may not match another. Confirm the timeline against a written list of plugins and a test plan rather than a generic estimate.
What does the work need from our internal team, and who owns the plugin afterward?
Your team needs to provide access to the Backstage app repository, a staging environment that mirrors production sign-in and catalog data, and a named reviewer who can decide on behavior changes. Someone who knows your catalog entities and the teams that use each plugin should validate the results. After the move, ownership stays with your organization. The community plugin is maintained by its own authors, so your team or partner owns the pinned version, the decision to upgrade it and any local patches. Agree on that owner in writing before the work starts.
Can our team do the plugin move ourselves using the upgrade guide?
Yes, many teams can, especially when only a few plugins are involved and the changes are dependency and import renames. The Backstage upgrade documentation describes the monthly process, and the Upgrade Helper shows template changes between versions. Teams usually struggle where a plugin changed configuration, where a deprecated package is still in use, or where version pins conflict with the @backstage packages in the same app. If your engineers have not run a version bump before, or if plugin failures appear only in staging, a fixed-scope engagement can cover that gap. Decide which plugins your team can handle and which need outside help.
How do we tell whether a community plugin is still maintained?
Check the plugin's repository activity, including recent commits, open issues, whether pull requests are merged, and whether releases track the current Backstage release line. Review the plugin's package metadata for the version it publishes and whether that version lists compatible Backstage peer dependencies. Look at who maintains it and whether the project has a stated maintenance policy. Also check the plugin's security reporting process and its license. A plugin with no release aligned to your current Backstage version is a risk even if the code still works, so record the check result and repeat it on each upgrade cycle.
What should we ask for in a fixed-scope quote for a plugin move?
Ask for a written list of every plugin in scope, with its current and target package name and version, and for each one a statement of what changes are expected in code, configuration and tests. The quote should state which Backstage release the work targets, how staging and production validation will be done, what is handed over (updated repository, test results, a short runbook and the pinned version list) and what is excluded, such as custom plugin development or unrelated upgrades. Ask how changes after sign-off are handled and whether any ongoing maintenance is a separate retainer. DeployOpen provides quotes based on a written scope, so the scope list is the first thing to prepare.
How DeployOpen scopes and delivers a plugin migration
DeployOpen approaches plugin migrations to the Backstage community-plugins repository as a scoped piece of work on your own Backstage app. We inventory the plugins that moved, agree the package changes and version pins in writing, then test and hand over a documented result you can run and review.
How we scope
- Inventory every plugin dependency in your app and flag those that left the core repository.
- Record the old and new package names, the matching @backstage release line, and the maintenance status of each plugin.
- Agree the written scope, deliverables and timeline before work starts, as most engagements are fixed-scope.
- Confirm which plugins are internal, which are community-maintained, and who owns the decision to replace or retire each one.
How we build
- Update package dependencies and pin versions that match your Backstage release, using the project's versions tooling where it applies.
- Apply code changes for renamed imports and changed plugin configuration keys in your frontend and backend packages.
- Run your existing build, lint and test suites, and add checks for any plugin route, entity card or catalog integration that changed.
- Record every pin and each deviation from the upstream release notes in the change log for your review.
How we hand over
- Deliver a dependency map listing each migrated plugin, its package name, pinned version and owning team.
- Document the update procedure your engineers need to repeat when a community plugin publishes a new release.
- Walk your platform engineers through the changes and the test results in a working session before sign-off.
- Provide the code, configuration and documentation in your own repository, under your control.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers, so plugin pins can be reviewed each release cycle.
- Ask your retainer scope to cover checking community plugin maintenance status before each Backstage upgrade.
- Confirm with the plugin maintainers which release lines they support before agreeing on a pinning policy.
- Agree in writing who reviews plugin release notes and who approves a pin change in your environment.

