Skip to main content

Build Module

The build module (@backstage/cli-module-build) handles building, starting, and packaging Backstage packages, both individually and across the repo.

For details on the build system itself, see the Build System documentation.

repo start​

Start a set of packages in the project for local development. If no explicit packages are listed via arguments or options, packages will instead be selected based on their package role. If a single set of frontend and/or backend packages are found, they will be started. If there are multiple matches the directories packages/app and packages/backend will be preferred. If no matches are found the command will fall back to expecting a single plugin frontend and/or backend package to start instead.

Any --config options in the start script in package.json of the selected packages will be picked up and used, unless a --config option is provided to this command, in which case it will be used instead.

Any --require option in the start script in package.json of the selected backend package will be picked up and used.

Usage: backstage-cli repo start [options] [packageNameOrPath...]

Starts packages in the repo for local development

Arguments:
packageNameOrPath Run the specified packages instead of the defaults.

Options:
--plugin <pluginId> Start the dev entry-point for any matching plugin package in the repo (default: [])
--config <path> Config files to load instead of app-config.yaml (default: [])
--inspect [host] Enable debugger in Node.js environments. Applies to backend package only
--inspect-brk [host] Enable debugger in Node.js environments, breaking before code starts. Applies to backend package only
--require <path> Add a --require argument to the node process. Applies to backend package only
--link <path> Link an external workspace for module resolution

repo build​

Builds all packages in the project, excluding bundled packages by default, that is, ones with the role 'frontend' or 'backend'.

Usage: backstage-cli repo build [options]

Build packages in the project, excluding bundled app and backend packages.

Options:
--all Build all packages, including bundled app and backend packages.
--since <ref> Only build packages and their dev dependents that changed since the specified ref

repo clean​

Remove cache and output directories across all packages in the project.

Usage: backstage-cli repo clean [options]

Delete cache and output directories

package start​

Starts the package for local development. See the frontend and backend development parts in the build system bundling section for more details.

Usage: backstage-cli package start [options]

Start a package for local development

Options:
--config <path> Config files to load instead of app-config.yaml (default: [])
--role <name> Run the command with an explicit package role
--check Enable type checking and linting if available
--require <path> Add a --require argument to the node process
--link <path> Link an external workspace for module resolution
--entrypoint <path> Entry directory path (uses index file) or entry file path (without extension). Defaults to "dev"
--inspect [host] Enable the Node.js inspector, optionally at a specific host:port
--inspect-brk [host] Enable the Node.js inspector and break before user code starts

package build​

Build an individual package based on its role. See the build system building and bundling sections for more details.

Usage: backstage-cli package build [options]

Build a package for production deployment or publishing

Options:
--role <name> Run the command with an explicit package role
--minify Minify the generated code. Does not apply to app package (app is minified by default).
--skip-build-dependencies Skip the automatic building of local dependencies. Applies to backend packages only.
--stats If bundle stats are available, write them to the output directory. Applies to app packages only.
--config <path> Config files to load instead of app-config.yaml. Applies to app packages only. (default: [])
--module-federation Build a package as a module federation remote. Applies to frontend plugin packages only.

package bundle​

Experimental

This command is experimental and may receive breaking changes in future releases without a deprecation period. It is hidden from the main --help output.

Bundle a plugin for dynamic loading. This creates a self-contained plugin package that can be deployed independently and loaded dynamically by a Backstage application. Supports both backend and frontend plugins.

Unlike regular builds, the bundle command:

  • Creates a fully self-contained plugin deliverable

  • Produces module federation assets (frontend) or includes plugin dependencies in the plugin's private node_modules, building and packing (with yarn pack) the local workspace:^ dependencies first (backend).

  • Generates a config schema from plugin-related packages only.

  • Validates that the plugin exports valid dynamic loading entry points (backend only)

Usage​

# Bundle the current package (output: ./bundle/)
yarn backstage-cli package bundle

# Bundle to a specific directory (output: ../dynamic-plugins/<mangled-package-name>/)
yarn backstage-cli package bundle --output-destination ../dynamic-plugins

# Override the bundle subdirectory name
yarn backstage-cli package bundle --output-name my-plugin-bundle

# Clean output before bundling
yarn backstage-cli package bundle --clean

# Skip building for the plugin and its local dependencies
yarn backstage-cli package bundle --no-build

# Skip dependency installation and entrypoint validation
yarn backstage-cli package bundle --no-install

# Stream detailed output from build, pack, and install steps
yarn backstage-cli package bundle --verbose

# Use a pre-built dist workspace for batch bundling.
# First, create the workspace with:
# backstage-cli build-workspace <output-dir> [packages...] --alwaysPack
# Then pass <output-dir> as --pre-packed-dir:
yarn backstage-cli package bundle --pre-packed-dir ../dist-workspace

Options​

Usage: backstage-cli package bundle [options]

Bundle a plugin for dynamic loading

Options:
--output-destination <dir> Directory in which the bundle subdirectory is created.
Defaults to the current package directory.
--output-name <name> Name of the bundle subdirectory. Defaults to "bundle" when
output stays in the package directory, or to the mangled
package name (e.g. myorg-plugin-foo) when
--output-destination is specified.
--clean Clean the output directory before bundling
--no-build Skip building packages (assumes they are already built)
--no-install Skip dependency installation and entrypoint validation.
--verbose Stream detailed output from internal steps (build, pack,
install) to the console. Without this flag, output is
captured to per-step log files and only shown on error.
--pre-packed-dir <dir> Path to a pre-built dist workspace (from
build-workspace --alwaysPack). Skips local dependency
packing and uses pre-packed packages directly. For frontend
plugins, this also enables yarn.lock generation for SBOM.

Output contract​

The bundle output is a directory that can be deployed as a standalone unit. Consumers of the bundle (such as @backstage/backend-dynamic-feature-service or @backstage/frontend-dynamic-feature-loader) can rely on the following guarantees:

All bundles:

  • A package.json at the bundle root with entry points configured for dynamic loading. The backstage.role and files fields are preserved from the source package.
  • A dist/ directory containing the built plugin code.
  • A dist/.config-schema.json file (when any config schemas apply) containing gathered schemas from the plugin, its local workspace dependencies, and third-party dependencies. Schemas from unrelated Backstage packages are excluded.
  • No scripts or devDependencies in package.json.

Backend plugins (backend-plugin, backend-plugin-module):

  • A node_modules/ directory with all production dependencies (including local workspace dependencies), pinned to their exact versions from the source lockfile.
  • bundleDependencies is set to true in package.json.

Frontend plugins (frontend-plugin, frontend-plugin-module):

  • main points to dist/remoteEntry.js (the Module Federation remote entry).
  • types points to dist/@mf-types/index.d.ts when type declarations are available.
  • No embedded node_modules/ directory.

Environment variables​

The bundle command supports the same environment variables as the Backstage yarn plugin for resolving backstage:^ version specifiers:

  • BACKSTAGE_MANIFEST_FILE: Path to a local manifest file (for offline usage)
  • BACKSTAGE_VERSIONS_BASE_URL: Custom base URL for fetching release manifests

Supported package roles​

The bundle command supports packages with the following roles:

  • backend-plugin
  • backend-plugin-module
  • frontend-plugin
  • frontend-plugin-module

package clean​

Remove cache directories.

Usage: backstage-cli package clean [options]

Delete cache directories

package prepack​

This command should be added as scripts.prepack in all packages. It enables packaging- and publish-time overrides for fields inside package.json. For more details, see the build system publishing section.

Usage: backstage-cli package prepack [options]

Prepares a package for packaging before publishing

package postpack​

This should be added as scripts.postpack in all packages. It restores package.json to what it looked like before calling the prepack command.

Usage: backstage-cli package postpack [options]

Restores the changes made by the prepack command

build-workspace​

Builds a mirror of the workspace using the packaged production version of each package. This essentially calls yarn pack in each included package and unpacks the resulting archive in the target workspace-dir.

Usage: backstage-cli build-workspace [options] <workspace-dir> [packages...]

Options:
--alwaysPack Force workspace output to be a result of running `yarn pack` on
each package (warning: very slow)

When --alwaysPack is used, the output directory can be passed to backstage-cli package bundle --pre-packed-dir to speed up batch bundling of multiple plugins from the same monorepo.