Skip to main content
In this lesson you’ll create a first Backstage scaffolder template and follow the end-to-end flow: author a blueprint, surface it in Backstage, run the template from the Create UI, and inspect the published repository and catalog registration. The example use case: your organization wants every Node.js API to include ESLint, Prettier, Jest, GitHub Actions CI/CD, and Express.js. A platform team can bake those standards into a template so developers get a ready-made starter repo when they scaffold a new service.
A slide titled "Steps We Will Perform" showing a diagram where a Platform Team and Developer fill out a "Form" to create a Demo-App. The flow points to a GitHub repository and a Template.yaml file as outputs.

Conceptual workflow

High-level flow for templated scaffolding:
  • Platform team maintains a blueprint repository with starter code (linter, formatter, tests, CI workflow, Express app).
  • The blueprint + its template.yaml descriptor are made available to Backstage (for example, registered via app-config.yaml static entries).
  • Developers open Backstage → Create → select the template → fill a brief form → the scaffolder:
    1. fetches the blueprint,
    2. renders files with the form values,
    3. creates a new GitHub repository and pushes the rendered files,
    4. registers the new service in the Backstage catalog.
Below is the example template that ships with Backstage and appears under Create → Templates.
A screenshot of the Backstage "Create a new component" page showing a Templates section with an "Example Node.js Template" card. The left sidebar displays navigation items like Home, APIs, Docs and Create, and a green cursor is visible on the screen.

Where does that example template come from?

Backstage can import static templates via app-config.yaml. A representative static entry that imports the local example template looks like this:
The target above points to the example template.yaml that Backstage imports and lists in the Create UI.

Minimal template.yaml example

A template descriptor follows the Scaffolder descriptor format. Here is a minimal cleaned template.yaml example:
Parameters map directly to the Backstage form:
  • name is a required string used as the project name.
  • repoUrl uses the RepoUrlPicker UI component and restricts allowed hosts to github.com.
When authoring or editing template YAML and template files in MDX content, always place expressions such as ${{ parameters.name }} or {{ values.name }} inside fenced code blocks or inline code backticks so MDX does not attempt to evaluate them.

How the template executes — steps

The scaffolder runs a sequence of steps defined under spec.steps. A canonical Node.js blueprint flow includes:
  1. Fetch the blueprint content and render it with provided values.
  2. Publish the rendered files to GitHub (create repo and push).
  3. Register the new service in the Backstage catalog.
A cleaned steps example:
Key points:
  • The fetch:template action copies and renders files from the blueprint ./content folder into a working directory. In this example we pass values.name as name using name: ${{ parameters.name }}.
  • The publish:github action creates the repository and pushes the rendered files. It requires the repoUrl input derived from the UI parameter.
  • The catalog:register action uses the repoContentsUrl output from the publish step and the catalogInfoPath (for example, /catalog-info.yaml) to register the entity in the catalog.

Scaffolder actions at a glance

Example blueprint content files

The blueprint content folder typically contains files that the scaffolder renders with template expressions. package.json (in content/package.json):
index.js (in content/index.js):
catalog-info.yaml (in content/catalog-info.yaml):
When the scaffolder runs:
  • It renders files by replacing template placeholders (e.g., package.json’s name becomes the project name entered in the UI because ${{ values.name }} is substituted).
  • The publish step uploads the rendered files to the created GitHub repository (using the repoUrl supplied by the user).
  • The register step registers the catalog-info.yaml entity in the Backstage catalog using repoContentsUrl from the publish step and the catalogInfoPath.

Outputs and UX

After a successful run, template.yaml’s output.links field surfaces useful links to the user:
  • Repository: steps['publish'].output.remoteUrl — opens the newly created repo.
  • Open in catalog: steps['register'].output.entityRef — opens the newly registered entity in Backstage.
This provides immediate access to both the code repo and the catalog entry.

Summary

Templates let platform teams encode organizational best practices into reproducible blueprints. With only a couple of form fields, Backstage can:
  • Create a new repository from a standardized blueprint,
  • Render project-specific values into files,
  • Publish the project to GitHub,
  • Register the service in the Backstage catalog.
You can author your own templates: create content in a content folder, write your template.yaml with spec.steps, and test the end-to-end scaffolding flow from the Backstage Create UI.

Watch Video