Skip to main content

Backstage New Frontend System - Comprehensive Guide

Version: Backstage v1.42.0+ Status: Complete Reference Documentation Last Updated: 2025-10-27

Overviewโ€‹

This documentation provides a comprehensive guide to Backstage's New Frontend System, an extension-based architecture that replaces the legacy frontend system. It includes practical examples, patterns, and best practices for building plugins and applications.

Purposeโ€‹

  • Developer Guide: Help developers build plugins and apps with the new frontend system
  • Migration Reference: Assist teams migrating from legacy to new frontend system
  • Practical Examples: Working code examples for common patterns and use cases
  • Best Practices: Extract patterns from Backstage core and community plugins

Key Benefits of the New Frontend Systemโ€‹

  • Extension-Based Architecture: Modular, composable, and declarative
  • Automatic Plugin Discovery: Install plugins via package.json, no manual imports
  • Configuration-Driven: Override extensions via app-config.yaml
  • Better Separation of Concerns: Clear boundaries between plugins, extensions, and APIs
  • Type-Safe: Strong TypeScript support throughout

๐Ÿ“š Documentation Structureโ€‹

Core Conceptsโ€‹

  1. Architecture Overview โญ START HERE

    • Extension tree architecture
    • Building blocks (App, Extensions, Plugins, Utility APIs)
    • Data flow and extension inputs/outputs
    • Comparison with legacy system
  2. App Creation & Configuration

    • Creating apps with createApp()
    • Feature discovery and installation
    • Plugin info resolution
    • App configuration patterns
  3. Extensions Deep Dive

    • Extension structure (ID, inputs, outputs, attachment points)
    • Creating extensions with createExtension()
    • Extension data references
    • Extension blueprints (PageBlueprint, ApiBlueprint, etc.)
    • Configuration schemas and factories
  4. Utility APIs

    • What are Utility APIs?
    • Creating API refs and implementations
    • Dependencies between APIs
    • Consuming APIs in components and extensions
  5. Auth Providers & Custom APIs

    • Standard auth API refs (GitHub, GitLab, OIDC, OAuth2)
    • How OAuth2.create() works
    • Frontend/backend separation
    • Registering custom auth providers
    • API factory patterns
    • OIDC and PKCE implementation
  6. Plugin Development

    • Plugin structure in new frontend system
    • Alpha exports (/alpha)
    • Creating frontend plugins with createFrontendPlugin()
    • Providing extensions from plugins
    • Plugin-to-plugin communication
  7. Migration Guide

    • Legacy vs New frontend system
    • Phase 1: Hybrid configuration
    • Phase 2: Complete transition
    • Migrating specific components (SignInPage, Sidebar, Routes)
    • Troubleshooting common issues

๐Ÿ’ก Practical Examplesโ€‹

All code examples are extracted from Backstage core and tested patterns:

App Creation Examplesโ€‹

Extension Examplesโ€‹

Utility API Examplesโ€‹

Auth Provider Examplesโ€‹

Plugin Examplesโ€‹


โ“ Requirements Questions & Answersโ€‹

This section maps all questions from new-frontend-system-deep-dive-requirements.md to their answers in the documentation.

Category 1: Frontend/Backend Separationโ€‹

โœ… Q1.1: Provider ID Mappingโ€‹

Question: How does the frontend know which backend auth providers are available?

Status: โœ… ANSWERED

Answer:

  • Frontend auth providers are registered independently from backend providers
  • No automatic discovery of backend providers by the frontend
  • Frontend creates auth API instances using OAuth2.create() with provider ID
  • The provider ID must match between frontend API and backend authenticator
  • Frontend makes requests to /api/auth/{provider}/start using the configured provider ID
  • Backend responds based on registered provider routes

Documentation: See 05-auth-providers.md ยง Frontend/Backend Separation

Example: examples/auth-providers/frontend-backend-matching.tsx


โœ… Q1.2: OAuth2 Generic Implementationโ€‹

Question: Is the OAuth2.create() implementation generic enough to work with any backend provider by name?

Status: โœ… ANSWERED

Answer:

  • YES, OAuth2.create() is completely generic and provider-agnostic
  • It only needs: configApi, discoveryApi, oauthRequestApi, and a provider ID
  • The same OAuth2 class handles all OAuth2/OIDC flows (GitHub, Google, Okta, custom OIDC, etc.)
  • Provider-specific logic is backend-only (scopes, client credentials, PKCE, etc.)
  • Frontend only handles: popup flow, token storage, refresh logic

Documentation: See 05-auth-providers.md ยง OAuth2.create() Deep Dive

Example: examples/auth-providers/oauth2-create-pattern.tsx


โœ… Q1.3: PKCE Transparencyโ€‹

Question: Is PKCE completely transparent to the frontend, handled entirely by the backend?

Status: โœ… ANSWERED

Answer:

  • YES, PKCE is 100% backend-transparent to the frontend
  • Frontend code is identical for PKCE vs client secret flows
  • code_challenge and code_verifier are generated and handled by backend only
  • Frontend only sees: standard OAuth2 authorization code flow
  • This confirms the hypothesis: zero custom frontend code needed for PKCE

Documentation: See 05-auth-providers.md ยง PKCE and Frontend Transparency

Key Insight: You can use the standard oidcAuthApiRef (or create a generic one) with a custom PKCE backend, requiring no custom frontend auth code.


Category 2: Standard Auth Provider API Referencesโ€‹

โœ… Q2.1: OIDC Auth API Referenceโ€‹

Question: Does Backstage core provide a standard oidcAuthApiRef?

Status: โš ๏ธ PARTIALLY ANSWERED

Answer:

  • NO standard oidcAuthApiRef exported from core packages (as of investigation)
  • However, provider-specific refs exist: oktaAuthApiRef, googleAuthApiRef, microsoftAuthApiRef, etc.
  • These all implement OAuthApi, OpenIdConnectApi, ProfileInfoApi, BackstageIdentityApi, and SessionApi
  • You can create your own generic oidcAuthApiRef using the same pattern
  • Or use a provider-specific ref (e.g., oktaAuthApiRef) even if your backend is custom OIDC

Documentation: See 05-auth-providers.md ยง Standard Auth API Refs

Example: examples/auth-providers/custom-oidc-ref.ts


โœ… Q2.2: Generic OAuth2 API Referenceโ€‹

Question: Is there a generic oauth2AuthApiRef that works with any OAuth2-compatible provider?

Status: โœ… ANSWERED

Answer:

  • NO generic oauth2AuthApiRef exported, but easy to create
  • All standard providers (GitHub, Google, Okta, etc.) use OAuth2.create() internally
  • Pattern: Create custom API ref + use OAuth2.create() with your provider ID
  • This is the recommended approach for custom OAuth2/OIDC providers

Documentation: See 05-auth-providers.md ยง Creating Custom Auth API Refs

Example: examples/auth-providers/generic-oauth2-ref.ts


Category 3: How Standard Providers Workโ€‹

โœ… Q3.1: GitHub Auth Registrationโ€‹

Question: How is githubAuthApiRef registered and made available in the New Frontend System?

Status: โœ… ANSWERED

Answer:

  • Standard providers are registered in @backstage/frontend-defaults
  • They are automatically available when using createApp() from @backstage/frontend-defaults
  • Registration happens via API extensions created with ApiBlueprint
  • Extensions attach to core extension's apis input
  • No manual registration needed for standard providers (GitHub, Google, etc.)

Documentation: See 05-auth-providers.md ยง How Standard Providers Are Registered

File Reference: backstage/packages/frontend-defaults/src/ (see investigation report)


โœ… Q3.2: Default API Factoriesโ€‹

Question: Does @backstage/frontend-defaults automatically register API factories for standard auth providers?

Status: โœ… ANSWERED

Answer:

  • YES, @backstage/frontend-defaults includes default API factories
  • Standard auth providers (GitHub, Google, Okta, etc.) are pre-registered
  • Also includes: configApi, discoveryApi, storageApi, errorApi, and more
  • This is why GitHub auth works "out of the box" without explicit registration
  • Custom auth providers must be registered manually using ApiBlueprint

Documentation: See 04-utility-apis.md ยง Default Utility APIs


Category 4: New Frontend System Extension Pointsโ€‹

โœ… Q4.1: API Registration Extension Pointโ€‹

Question: What is the correct extension point for registering custom API implementations?

Status: โœ… ANSWERED

Answer:

  • Use ApiBlueprint.make() to create API extensions
  • API extensions attach to core extension's apis input automatically (handled by blueprint)
  • Register via createFrontendModule() and add to app's features array
  • Pattern:
    const myApi = ApiBlueprint.make({
    name: 'my-api',
    params: {
    api: myApiRef,
    deps: { configApi: configApiRef },
    factory: ({ configApi }) => new MyApiImpl({ configApi }),
    },
    });

    const myModule = createFrontendModule({
    pluginId: 'app',
    extensions: [myApi],
    });

    createApp({ features: [myModule] });

Documentation: See 04-utility-apis.md ยง Registering Custom APIs

Example: examples/utility-apis/api-registration-complete.tsx


โœ… Q4.2: Extension Data Types for APIsโ€‹

Question: What is the correct way to use coreExtensionData for API factories?

Status: โœ… ANSWERED

Answer:

  • Don't use coreExtensionData.apiFactory directly when using blueprints
  • ApiBlueprint handles all extension data internally
  • If using createExtension() directly (not recommended for APIs):
    • Import apiFactoryDataRef from @backstage/frontend-plugin-api
    • Return [apiFactoryDataRef(factory)] from factory function
  • Recommendation: Always use ApiBlueprint.make() for APIs

Documentation: See 03-extensions.md ยง Extension Data References


โœ… Q4.3: ApiBlueprint vs createExtensionโ€‹

Question: When should we use ApiBlueprint.make() vs createExtension() for API registration?

Status: โœ… ANSWERED

Answer:

  • ALWAYS use ApiBlueprint.make() for Utility APIs
  • createExtension() is low-level and requires manual extension data handling
  • ApiBlueprint provides:
    • Correct attachment point (to core/apis)
    • Proper extension data output (apiFactoryDataRef)
    • Type safety and validation
    • Consistent naming patterns
  • createExtension() is for advanced custom extension types only

Documentation: See 04-utility-apis.md ยง API Blueprints vs createExtension


Category 5: Custom Auth Provider Supportโ€‹

โœ… Q5.1: Custom Provider Support Statusโ€‹

Question: Are custom auth providers officially supported in New Frontend System v1.42.0+?

Status: โœ… ANSWERED

Answer:

  • YES, fully supported via ApiBlueprint pattern
  • Same mechanism used internally for standard providers
  • Well-documented pattern (though scattered across docs)
  • Production-ready and stable
  • Recommended approach: ApiBlueprint.make() + OAuth2.create()

Documentation: See 05-auth-providers.md ยง Custom Provider Support


โœ… Q5.2: Provider Override Patternโ€‹

Question: Can a custom backend module override a standard provider?

Status: โœ… ANSWERED

Answer:

  • YES, through extension overrides
  • Frontend: Create API extension with same ID as standard provider
  • Backend: Register backend module with same provider ID
  • Last-registered extension wins (frontend), modules extend backend
  • Useful for: customizing GitHub scope, adding PKCE to OIDC, etc.

Documentation: See 05-auth-providers.md ยง Overriding Standard Providers

Example: examples/auth-providers/override-github-scopes.tsx


###Category 6: Migration Patterns

โœ… Q6.1: Legacy vs New Frontend Comparisonโ€‹

Question: What changed in auth provider registration between Legacy and New Frontend Systems?

Status: โœ… ANSWERED

Answer:

AspectLegacy Frontend SystemNew Frontend System
RegistrationcreateApiFactory() in apis.tsApiBlueprint.make() in module
InstallationPass to createApp({ apis: [...] })Pass to createApp({ features: [module] })
Locationpackages/app/src/apis.tspackages/app/src/modules/ or plugin
DiscoveryManual import requiredCan use automatic discovery
OverrideReplace in apis arrayExtension override or feature order
ConfigurationCode onlyCan use app-config.yaml

Documentation: See 07-migration.md ยง Migrating Auth Providers

Example: examples/auth-providers/legacy-vs-new-comparison.tsx


โœ… Q6.2: Missing Migration Documentationโ€‹

Question: Is there migration documentation for custom auth providers specifically?

Status: โš ๏ธ PARTIALLY ANSWERED

Answer:

  • Limited official migration docs for custom auth providers
  • General migration guide covers API factories โ†’ ApiBlueprint pattern
  • No specific "OIDC with PKCE" migration guide
  • This documentation fills that gap
  • Official docs focus on standard providers (GitHub, Google, etc.)

Documentation: This guide serves as the missing documentation

See: 07-migration.md ยง Auth Provider Migration Details


๐ŸŽฏ Key Takeawaysโ€‹

1. Extension-Based Architectureโ€‹

  • Everything is an Extension: Apps, plugins, pages, APIs, themes
  • Tree Structure: Extensions form a hierarchical tree
  • Configuration-Driven: Override behavior via app-config.yaml without code changes

2. Simplified Developmentโ€‹

  • Blueprints: Pre-built patterns for common extension types

    • PageBlueprint for pages
    • ApiBlueprint for utility APIs
    • SignInPageBlueprint for sign-in pages
    • ThemeBlueprint for themes
  • Feature Discovery: Auto-discover plugins from package.json

    • Add plugin to dependencies
    • Enable app.packages: all in config
    • No manual imports needed

3. Clean Separation of Concernsโ€‹

  • Frontend/Backend Independence: Clear boundaries between layers
  • Type Safety: Strong TypeScript support throughout
  • Testability: Easy to mock and test components
  • Modularity: Plugins are self-contained and reusable

4. Migration Pathโ€‹

  • Hybrid Mode: Run both systems side-by-side during migration
  • Incremental: Migrate one plugin at a time
  • Backward Compatible: Plugins can support both systems

๐Ÿ“– Additional Resourcesโ€‹

Backstage Official Docsโ€‹

Source Code Referenceโ€‹

  • Core Frontend Packages: backstage/packages/frontend-*
  • Core Auth Implementation: backstage/packages/core-app-api/src/apis/implementations/auth/
  • Frontend Defaults: backstage/packages/frontend-defaults/
  • Auth Backend: backstage/plugins/auth-backend/
  • OIDC Provider Module: backstage/plugins/auth-backend-module-oidc-provider/

Community Resourcesโ€‹


๐Ÿงช Testing Examplesโ€‹

Running Examples Locallyโ€‹

All examples can be tested by:

  1. Creating a new Backstage app with npx @backstage/create-app --next
  2. Copying example code into appropriate files
  3. Running yarn dev to test

Example Docker Setup (Bonus)โ€‹

For quickly testing examples:

# Build a test image with Backstage v1.42.0+
docker build -t backstage-test -f Dockerfile.test .

# Run with example mounted
docker run -it -v $(pwd)/examples:/app/examples backstage-test

# Inside container
cd /app && yarn dev

See examples/README.md for Docker setup details.


๐Ÿค Contributingโ€‹

Found an error or want to improve the documentation?

  1. Check existing issues: GitHub Issues
  2. Create a PR with your changes
  3. Update the requirements tracking if you answer new questions

๐Ÿ“… Document Maintenanceโ€‹

  • Created: 2025-10-27
  • Backstage Version: v1.42.0+
  • Status: Complete
  • Next Review: When Backstage releases major frontend system changes

Navigation: