Presenters

Source

🚀 Stop Rebuilding Your Backstage App: The Power of Dynamic Runtime Plugins

In the world of internal developer portals, Backstage stands as the industry titan. However, anyone who has managed a large-scale instance knows the “banana and the rainforest” problem: you want a simple plugin, but you end up pulling in a massive web of transitive dependencies that bloat your build and slow your CI/CD pipeline to a crawl.

At a recent talk, David Festal and Jon Koops from the Red Hat Developer Hub (RHDH) team unveiled a game-changing alternative to the traditional monolithic build. They shared a vision where you no longer bake plugins into your application at compile time. Instead, you install them at runtime.


🏗️ The Traditional Monolith: A Double-Edged Sword

Traditionally, Backstage architecture relies on a static build process. You add a plugin as an NPM dependency, run a build, and deploy a single, massive artifact.

The Benefits

  • Compile-time guarantees and type safety.
  • A single artifact for deployment.
  • Predictable versioning.

The Trade-offs ⚖️

  • CI Performance Bottlenecks: Every single plugin addition requires a full rebuild of the entire application.
  • Limited Developer Autonomy: A central team often becomes a bottleneck for merging and updating plugins.
  • Fragile Dependencies: Transitive dependencies can introduce instabilities.
  • Security Gridlock: If one plugin has a vulnerability, it can block the entire deployment pipeline for the whole portal.

💡 A New Vision: Modular Deployment

David and Jon propose shifting the plugin lifecycle away from the main application. Instead of a monolithic build, they advocate for modular deployment. This approach separates the life cycles of the core Backstage app and its plugins, allowing teams to update features without touching the main container image.

The Evolution of the Core 🛠️

This shift became possible thanks to massive modularization efforts in the Backstage core. The introduction of the new backend and frontend systems created strict encapsulation. Now, a plugin is a single entry point that handles its own initialization logic.

Two key packages now live in the upstream Backstage repository to facilitate this:

  1. Backend Dynamic Feature Service: Discovers and loads plugin “bundles” from a disk folder at startup.
  2. Frontend Dynamic Feature Loader: Works with the backend to load these features directly into the browser.

📦 Bundling: The Secret Sauce

You cannot simply point Backstage at source code and expect it to run. You must provide self-contained, standalone bundles.

  • Backend Bundles: These must include all private dependencies (e.g., a Kubernetes client for a Kubernetes plugin).
  • Frontend Bundles: These use Module Federation to act as remote modules that the browser gathers at loading time.

The final piece of the puzzle, the backstage-cli package bundle --experimental command, landed in the upstream repository just last week. This tool creates the necessary metadata, manifests, and isolated node_modules required for dynamic consumption.


🌐 Going Cloud-Native with OCI and Kubernetes

While loading from a local disk is great for development, David and Jon demonstrated a sophisticated production workflow using OCI (Open Container Initiative) registries.

The Workflow 🚀

  1. Build the plugin bundle once.
  2. Push the bundle as an OCI artifact (similar to a Helm chart or Wasm module) using tools like Crane, Podman, or Docker.
  3. Mount the artifact in Kubernetes using the Image Volumes feature (currently in beta/stable state).

This method leverages the best of the cloud-native ecosystem: immutability, security via SBOMs, provenance tracking, and caching.

The Live Demo 💻

During the presentation, the speakers demonstrated a rolling upgrade. By simply updating a Helm chart to include a new extraVolume and extraVolumeMount pointing to an OCI plugin bundle, the Backstage instance picked up a new Announcements plugin in just 3 seconds after the pod refreshed—without any code rebuild.


❓ Questions and Answers

Audience Member: Does this work for updating existing plugins, and how do you handle configuration or secrets for new ones? David Festal: Adding a dynamic plugin still requires configuration in your app-config. However, you manage this at the infrastructure level (like Kubernetes ConfigMaps or Vault integration) rather than the code level. You still avoid the rebuild.

Audience Member: Are there plans to extend this to other types of plugins, like Terraform or Crossplane? David Festal: We want to remain as unopinionated as possible. The system currently loads subfolders from a root directory. This gives you the freedom to build any distribution method on top of that infrastructure layer.


🗺️ The Road Ahead

The journey toward a fully dynamic Backstage has just begun. The team outlined several exciting next steps:

  • ✨ Providing dedicated templates for minimal Backstage apps with dynamic loaders.
  • ✨ Streamlining OCI distribution directly into the Backstage CLI.
  • ✨ Integrating security steps like automatic SBOM generation into the bundling process.
  • ✨ Creating a catalog of ready-to-use, off-the-shelf standalone bundles.

The Red Hat team encourages the community to experiment with these tools today and provide feedback via social channels. It is time to stop building monoliths and start composing platforms! 🦾🌐🎯

Appendix