About using-backstage-backend-system
A skill for developers defining Backstage backend plugins, modules, and extension points. It explains how to choose the right structure and wire registrations, dependencies, and extension points correctly.
Key features
- 01Plugin and module structure guidance
- 02Extension point definition patterns
- 03Registration and dependency wiring
- 04Plugin and module ID constraints
- 05Scoped and root service distinctions
Use cases
- 01Creating a backend plugin
- 02Building a module for an existing plugin
- 03Choosing between a plugin and module
- 04Exposing extension points to modules
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ vinzscam/ backstage-skills --skill using-backstage-backend-systemAfter installing, type/using-backstage-backend-systemin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/extension-points.mdmodules.mdplugin-definition.mdDetails
From the project READMEBackstage Backend System Patterns
When to use this skill
- Defining a new backend plugin (
src/plugin.ts) - Defining a backend module (
src/module.ts) that extends another plugin - Choosing between a full plugin vs a module
- Exposing extension points so other modules can extend your plugin
Choose the right pattern
| Building... | Pattern | Reference |
|---|---|---|
| The plugin itself | createBackendPlugin({ pluginId, register }) | references/plugin-definition.md |
| A module that extends another plugin | createBackendModule({ pluginId, moduleId, register }) | references/modules.md |
| An extension point so other modules can extend yours | createExtensionPoint<T>({ id }) | references/extension-points.md |
Two invocation modes
- Standalone: editing an existing backend plugin/module.
- Post-scaffold (called by
creating-backstage-pluginforbackend-plugin,backend-plugin-module,catalog-provider-module,scaffolder-backend-module): wire up the canonical structure (src/plugin.tsorsrc/module.ts,src/index.tsre-export).
Common gotchas
- All wiring imports come from
@backstage/backend-plugin-api, not@backstage/core-plugin-api(which is frontend-only). - The
register(env)callback receives an environment object withenv.registerInit({ deps, async init })andenv.registerExtensionPoint(point, impl).depsis a map of service refs the init function needs;initreceives the resolved instances. registerInitmay be called only once per plugin/module.registerExtensionPointmust be called beforeregisterInit.- Plugin-scoped vs root-scoped services: most refs (
logger,httpRouter,database,scheduler,auth,httpAuth,userInfo,cache,discovery,urlReader,lifecycle,permissions) are plugin-scoped — each plugin gets its own instance with plugin-aware behavior (e.g. logger pre-tagged withpluginId, database giving a per-plugin schema). Six refs (rootConfig,rootLogger,rootLifecycle,rootHealth,rootHttpRouter,rootInstanceMetadata) are root-scoped — single shared instance. Both can be depended on from a plugin'sregisterblock; the distinction matters for behavior, not for injection syntax. - A plugin's
pluginIdand a module'smoduleIdmust match the pattern[a-z][a-z0-9-]*(letters, digits, dashes; starts with a letter). - Modules depend on the extension points exported by the target plugin's library package (e.g.
@backstage/plugin-catalog-node), not on the plugin's main package.
Comments
Markdown supported