Build a Developer Portal with Backstage
Set up a local Backstage portal with a Software Catalog and Templates.
Introduction
30 Second Summary
Imagine joining a company with hundreds of services, and nobody knows who owns what or where to find the documentation. Every team has its own setup process, its own project structure, and its own way of naming things.
In this project, you will build a local Backstage developer portal that solves exactly this problem. You will set up a Software Catalog to track services in one place, then build a Software Template that scaffolds new projects through a guided form.
What You'll Build
A fully functional local Internal Developer Portal powered by Backstage, demonstrating how platform teams centralize service ownership and standardize project creation.
By the end of this project, you'll have:
- A running Backstage instance with a populated demo catalog you can browse and explore.
- A custom component registered in the Software Catalog that represents your own service, complete with ownership metadata.
- A working Software Template that scaffolds new Node.js microservice projects from a form with your inputs baked in.
- Secret Mission: Create a second template that scaffolds a documentation site with TechDocs integration.
Are there any prerequisites?
You should be comfortable running commands in a terminal and have basic familiarity with YAML files. No prior Backstage experience is needed.
Install Node.js and Yarn
Backstage requires specific versions of Node.js and Yarn to run properly. Getting these set up first means you won't hit cryptic errors later when scaffolding and running your portal.
In this step, you'll install Node.js 22 using a version manager called nvm, then activate Yarn through Node's built-in Corepack feature.
In this step, get ready to:
- Install Node.js 22 using nvm.
- Enable Corepack and set Yarn to version 4.4.1.
Install Node.js 22 using nvm
nvm (Node Version Manager) lets you install and switch between multiple versions of Node.js. Backstage requires Node 22, so you'll use nvm to install exactly that version.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal (macOS) or PowerShell (Windows) and press Enter to open it.
- Check if you already have Node.js installed by running this command:
node --version
✔️ I see version 22 or higher
Your Node.js version is ready for Backstage. Skip ahead to the Yarn setup section below.
ⓧ I see an older version
You have Node.js installed, but Backstage needs version 22. Install nvm to manage versions, then use it to install Node 22.
macOS
- Install nvm by running this command:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
- Close your terminal and open a new one so the changes take effect.
- Install and activate Node 22 by running:
nvm install 22
Windows
Windows uses a different tool called nvm-windows.
- Download the latest installer from the nvm-windows releases page:
https://github.com/coreybutler/nvm-windows/releases
- Run the installer and follow the prompts.
- Close PowerShell and reopen it as Administrator (right-click, Run as administrator).
- Install Node 22 by running:
nvm install 22
- Activate it by running:
nvm use 22
- Verify the installation by running:
node --version
You should see a version number starting with v22.
ⓧ Command not found
Node.js is not installed yet. You'll install nvm first, then use it to install Node 22.
macOS
- Install nvm by running this command:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
- Close your terminal and open a new one so the changes take effect.
- Install and activate Node 22 by running:
nvm install 22
Windows
Windows uses a different tool called nvm-windows.
- Download the latest installer from the nvm-windows releases page:
https://github.com/coreybutler/nvm-windows/releases
- Run the installer and follow the prompts.
- Close PowerShell and reopen it as Administrator (right-click, Run as administrator).
- Install Node 22 by running:
nvm install 22
- Activate it by running:
nvm use 22
- Verify the installation by running:
node --version
You should see a version number starting with v22.
What is nvm?
nvm stands for Node Version Manager. It lets you install multiple versions of Node.js on the same machine and switch between them with a single command.
This is useful because different projects often require different Node versions. With nvm, you avoid conflicts between projects.
Still seeing an older version or command not found?
Make sure you closed and reopened your terminal after installing nvm. The nvm command only becomes available in new terminal sessions.
On macOS, if you still see the error after reopening, run source ~/.zshrc to reload your shell configuration.
help me troubleshoot my nvm or Node.js installation issue
Enable Corepack and set Yarn version
Backstage uses Yarn as its package manager. Node.js ships with a tool called Corepack that manages Yarn versions for you.
- Enable Corepack by running this command:
corepack enable
What is Corepack?
Corepack is a built-in Node.js tool that acts as a bridge to package managers like Yarn and pnpm. Running corepack enable activates it so you can use Yarn without installing it separately.
- Set the Yarn version to 4.4.1 (the version Backstage requires) by running:
yarn set version 4.4.1
What does this command do?
The yarn set version 4.4.1 command downloads and pins this specific Yarn version. Backstage requires this exact version for compatibility.
- Verify Yarn is working by running:
yarn --version
You should see 4.4.1 printed in the terminal.
Seeing a permission error with corepack enable?
On macOS or Linux, you may need to prefix the command with sudo (for example, sudo corepack enable).
On Windows, make sure you are running PowerShell as Administrator.
help me fix a permission error when running corepack enable
Your development environment is ready. Next up, you'll use these tools to scaffold your Backstage app.
Create Your Backstage App
Your development environment is locked and loaded. Node.js and Yarn are ready to power a full Backstage application.
In this step, you will scaffold a brand new Backstage app, start it up locally, and explore the built-in demo catalog. This gives you a feel for how a developer portal works before you customize anything.
In this step, get ready to:
- Scaffold a new Backstage application using the official CLI.
- Start the app and open it in your browser.
- Explore the demo Software Catalog and navigation.
Run the create-app command
Backstage provides an official scaffolding tool that generates an entire portal application from a single command. It sets up the frontend, backend, configuration files, and demo data so you can start exploring immediately.
- Move to your Desktop by running this command:
cd ~/Desktop
- Scaffold a new Backstage app by running this command:
npx @backstage/create-app@latest
What will this command ask you?
The wizard asks two things. First, if this is your first time running the command, it asks permission to install the @backstage/create-app package. Type y and press Enter to proceed.
Second, it prompts you for the app name. Type my-portal and press Enter. The tool then creates the project folder, copies template files, and installs all dependencies. This takes a few minutes.
- When prompted with Enter a name for the app [required], type my-portal and press Enter.
- Wait for the process to finish. You should see a message containing Successfully created my-portal when it is done.
- Confirm the project folder exists by running:
ls
You should see my-portal listed in the output.
Don't see my-portal in the output?
- Make sure you ran the command from ~/Desktop. If you were in a different directory, the folder was created there instead.
- Check that the process completed without errors. If you see a network timeout, verify your internet connection and try again.
- Confirm you typed my-portal when prompted for the app name. The folder name matches whatever you entered.
Help me troubleshoot why my Backstage create-app command failed.
Start the app
With the project scaffolded, you can start both the frontend and backend from a single command. Backstage runs the frontend on port 3000 and the backend on port 7007.
- Navigate into your project and start the development server by running these commands:
cd my-portal
yarn start
- Watch the terminal output. When you see the message Rspack compiled successfully, the frontend is ready.
- Open your browser and navigate to http://localhost:3000.
You should see the Backstage home page with a welcome screen and navigation sidebar on the left.
What is yarn start doing?
The yarn start command runs both the frontend and backend as separate processes in one terminal window. The backend loads plugins like the Software Catalog and Software Templates from the app-config.yaml file.
The frontend compiles using Rspack and serves the portal UI. You will see output lines from both processes as they initialize.
Page not loading at localhost:3000?
- Make sure you waited for Rspack compiled successfully before opening the browser. The frontend takes a moment to bundle.
- Check if another application is already using port 3000. Close any other dev servers and try yarn start again.
- If you see permission errors, make sure you ran corepack enable in the previous step.
Why isn't my Backstage app loading in the browser?
Explore the demo catalog
Your Backstage instance comes pre-loaded with demo data so you can see what a populated portal looks like. The two core features are the Software Catalog (where you track all your software) and Software Templates (where you scaffold new projects).
- In the left sidebar, click Catalog. This takes you to /catalog, the Software Catalog.
- Browse the list of demo components. Click on any component name to see its detail page.
- On the detail page, notice the metadata displayed: owner, lifecycle, type, and description.
- Navigate back to the sidebar and click Create.... This takes you to /create, the Software Templates page.
- Note the Docs link in the sidebar as well. These three navigation items (Catalog, Create, Docs) are the core of the Backstage experience.
What is the Software Catalog?
The Software Catalog is a centralized registry of all the software your organization owns. Each entry (called an entity) is defined by a YAML file that describes its type, owner, lifecycle stage, and relationships to other entities.
In a real company, every microservice, website, library, and database would have a catalog entry. This makes it easy to answer questions like "who owns this service?" or "what does this team maintain?"
Your portal is up and running with a full demo catalog. Next up, you will register your own custom component to see how teams add their services to the catalog.
Register a Custom Component
The demo catalog shows how Backstage displays software metadata, but a real developer portal needs entries for your team's actual services.
In this step, you'll define your own service as a catalog entity by writing a YAML descriptor file. Then you'll point Backstage at it so your service appears alongside everything else in the Software Catalog.
In this step, get ready to:
- Create a catalog-info.yaml file describing a service you own.
- Register the file in Backstage's configuration.
- Verify your custom component appears in the catalog.
Create a catalog-info.yaml file
Every piece of software tracked in Backstage is described by a YAML file called catalog-info.yaml. This file declares what the software is, who owns it, and where it sits in its lifecycle.
- Open a new terminal tab or window. Your existing terminal is busy running yarn start.
- Create the my-service directory in your home folder by running this command:
mkdir ~/my-service
- Create and open a new file called catalog-info.yaml inside ~/my-service/ using your code editor.
- Paste the following YAML into the file:
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-payment-service
description: Handles payment processing for the checkout flow
annotations:
backstage.io/techdocs-ref: dir:.
tags:
- nodejs
- payments
spec:
type: service
lifecycle: production
owner: team-payments
What does this file do?
This YAML file is a catalog entity descriptor. It tells Backstage everything it needs to know about a piece of software.
- apiVersion: backstage.io/v1alpha1 and kind: Component identify this as a Backstage component entity.
- metadata provides the name, description, tags, and annotations that show up in the catalog UI.
- spec.owner declares which team is responsible for this service.
- spec.lifecycle marks the service as production, meaning it is live and actively maintained.
- Save catalog-info.yaml.
- Confirm the file exists by running:
ls ~/my-service
You should see catalog-info.yaml in the output.
Don't see the file?
Make sure you created the directory with mkdir ~/my-service before saving the file there. If you saved it in the wrong location, move it with mv or re-save from your editor into ~/my-service/.
Help me find my catalog-info.yaml file.
Register it in Backstage
Backstage needs to know where your entity file lives. You tell it by adding a location entry to app-config.yaml.
- In your code editor, open app-config.yaml at the root of the my-portal directory.
- Scroll down to the catalog: section. You'll see a locations: array that already has entries for the demo data.
- Add the following entry at the end of the locations: list:
- type: file
target: ../../my-service/catalog-info.yaml
rules:
- allow: [Component]
What does this configuration do?
This location entry tells Backstage to look for a catalog entity file at the given path. The type: file means it reads from the local filesystem.
The ../../my-service/catalog-info.yaml path is relative to the backend's execution path. The rules array restricts what kinds of entities this file is allowed to define. Here only Component is permitted.
- Save app-config.yaml.
Unsure where to paste?
Look for the existing catalog: key in your file, then find locations: nested beneath it. Paste the new entry at the same indentation level as the existing list items (the - type: lines). YAML is indentation-sensitive, so make sure the spacing matches.
Help me find the right place to add my catalog location in app-config.yaml.
Verify in the catalog
Backstage reads app-config.yaml at startup. To pick up your new location entry, you need to restart the app.
- Switch back to the terminal where yarn start is running.
- Press Ctrl+C to stop the process.
- Restart Backstage by running:
yarn start
- Wait for the Rspack compiled successfully message to appear.
- Open http://localhost:3000/catalog in your browser.
- If you don't see your component immediately, click the Kind dropdown and select Component, or clear any active filters.
You should see my-payment-service listed in the catalog with owner team-payments and lifecycle production.
What should I see?
Your component appears as a row in the catalog table. Clicking on it opens a detail page showing the description, tags, owner, and lifecycle you defined in catalog-info.yaml. This is the same view structure you explored for the demo components earlier.
Don't see my-payment-service?
Check that your YAML indentation in app-config.yaml is correct. The - type: file line must be at the same indent level as the other location entries.
Also confirm that ~/my-service/catalog-info.yaml exists and has no YAML syntax errors. You can check for errors in your terminal output after restarting.
Help me troubleshoot why my component isn't showing in the Backstage catalog.
✔️ Awesome, I've got everything!
Great. Double check you've saved both files, then move on to the next step.
ⓧ I'd like to double check the full code
Here is the complete catalog-info.yaml file:
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-payment-service
description: Handles payment processing for the checkout flow
annotations:
backstage.io/techdocs-ref: dir:.
tags:
- nodejs
- payments
spec:
type: service
lifecycle: production
owner: team-payments
And here is the entry you added to app-config.yaml under catalog.locations:
- type: file
target: ../../my-service/catalog-info.yaml
rules:
- allow: [Component]
Your service is now part of the catalog. Next up, you'll build a Software Template that lets anyone on your team scaffold new services from a guided form.
Build a Software Template
You've registered a custom component in the catalog, proving that Backstage can track any service your team owns. Now it's time to tackle the second superpower of Backstage: Software Templates.
Software Templates solve the problem of inconsistent project setup. Instead of every developer copy-pasting boilerplate and forgetting half the config, a template generates a ready-to-go project skeleton through a simple form. You'll build one that scaffolds a Node.js microservice complete with a health endpoint and catalog registration.
In this step, get ready to:
- Create a template directory with skeleton files.
- Write a template definition that presents a form and scaffolds a project.
- Register and run the template from the Backstage UI.
Create the template directory structure
A Backstage template lives in two parts: a template.yaml that defines the form and scaffolding logic, and a template/ directory containing the skeleton files that get copied and rendered with the user's inputs.
- Open a new terminal tab or window (your existing terminal is running yarn start).
- Navigate into your my-portal directory and create the template folder structure by running these commands:
cd ~/Desktop/my-portal
mkdir -p templates/node-service/template/src
What does this create?
This creates a nested folder structure: templates/node-service/ holds the template definition, and templates/node-service/template/src/ holds the skeleton source code that gets generated for each new project.
- Confirm the directories exist by running:
ls templates/node-service/
You should see a template directory listed in the output.
Now you'll create the skeleton files that every scaffolded project will receive. Start with the package manifest.
- In your code editor, create a new file at templates/node-service/template/package.json and paste in the following code:
{
"name": "${{ values.name }}",
"version": "1.0.0",
"description": "Microservice: ${{ values.name }}",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"dev": "node --watch src/index.js"
}
}
What does this code do?
This is a standard Node.js package manifest, but with ${{ values.name }} placeholders instead of hardcoded names. When someone runs your template, Backstage replaces these placeholders with the values they entered in the form.
The dev script uses node --watch so the scaffolded service auto-restarts on file changes during development.
- Save package.json.
Next, create the main application file for the skeleton service.
- Create a new file at templates/node-service/template/src/index.js and paste in the following code:
const http = require('http');
const PORT = process.env.PORT || 3001;
// Create an HTTP server that responds with service health info
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
service: '${{ values.name }}',
status: 'healthy',
timestamp: new Date().toISOString()
}));
});
// Start the server on the configured port
server.listen(PORT, () => {
console.log(`${{ values.name }} running on port ${PORT}`);
});
What does this code do?
This creates a minimal HTTP server that returns JSON health information. The ${{ values.name }} placeholder appears in the response body and console log, so the scaffolded service identifies itself by whatever name the developer chose in the form.
It listens on port 3001 by default (or whatever PORT environment variable is set), keeping it separate from Backstage's port 3000.
- Save index.js.
Finally, add a catalog descriptor so the scaffolded service automatically registers itself in Backstage.
- Create a new file at templates/node-service/template/catalog-info.yaml and paste in the following code:
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: ${{ values.name }}
description: Microservice - ${{ values.name }}
spec:
type: service
lifecycle: experimental
owner: ${{ values.owner }}
What does this code do?
This is the same catalog entity format you used in the previous step, but with templated values. Every project generated from this template will ship with its own catalog-info.yaml, ready to be registered in Backstage.
The lifecycle is set to experimental because newly scaffolded services start in an early stage before moving to production.
- Save catalog-info.yaml.
- Confirm all three skeleton files are in place by running:
ls templates/node-service/template/
You should see catalog-info.yaml, package.json, and src listed.
Missing files or directories?
Make sure you created the files inside templates/node-service/template/ (not templates/node-service/ directly). The template/ subdirectory is what the fetch:template action reads from.
Also confirm index.js is inside template/src/, not directly inside template/.
Help me fix my template directory structure.
Write the template definition
The skeleton files are ready. Now you need the template.yaml that tells Backstage what form fields to show and how to render the skeleton with the user's inputs.
- Create a new file at templates/node-service/template.yaml and paste in the following code:
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: node-service-template
title: Node.js Microservice
description: Creates a new Node.js microservice with standard project structure
spec:
owner: platform-team
type: service
# Form fields shown to the user
parameters:
- title: Provide service details
required:
- name
- owner
properties:
name:
title: Service Name
type: string
description: Unique name for your new service
ui:autofocus: true
owner:
title: Owner
type: string
description: The team that will own this service
# Actions that run after the form is submitted
steps:
- id: fetchBase
name: Fetch Base
action: fetch:template
input:
url: ./template
values:
name: ${{ parameters.name }}
owner: ${{ parameters.owner }}
# Links shown after the template completes
output:
links:
- title: Open project directory
url: file://${{ steps.fetchBase.output.resultsPath }}
What does this code do?
- apiVersion: scaffolder.backstage.io/v1beta3 tells Backstage this is a Software Template using the v1beta3 schema.
- parameters defines the form. Each property becomes a field. The required array ensures both fields must be filled.
- steps defines what happens after submission. The fetch:template action reads the ./template directory, replaces all ${{ values.* }} placeholders with the form inputs, and writes the result.
- output provides a link to the generated files after the template finishes running.
Why ${{ parameters.name }} vs ${{ values.name }}?
Inside template.yaml you reference form inputs with ${{ parameters.name }}. Inside the skeleton files (the template/ directory), you use ${{ values.name }} because values are what the fetch:template action passes in from its input.values mapping.
- Save template.yaml.
YAML indentation issues?
YAML is strict about indentation. Make sure you use spaces (not tabs) and that nested keys are indented consistently by 2 spaces. If you see parse errors later, check that parameters, steps, and output are all at the same indentation level under spec:.
Help me fix my template.yaml formatting.
✔️ Awesome, I've got everything!
Great. Double check you've saved all your files before moving on.
ⓧ I'd like to double check the full code
Here is the full template.yaml:
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: node-service-template
title: Node.js Microservice
description: Creates a new Node.js microservice with standard project structure
spec:
owner: platform-team
type: service
parameters:
- title: Provide service details
required:
- name
- owner
properties:
name:
title: Service Name
type: string
description: Unique name for your new service
ui:autofocus: true
owner:
title: Owner
type: string
description: The team that will own this service
steps:
- id: fetchBase
name: Fetch Base
action: fetch:template
input:
url: ./template
values:
name: ${{ parameters.name }}
owner: ${{ parameters.owner }}
output:
links:
- title: Open project directory
url: file://${{ steps.fetchBase.output.resultsPath }}
Here is the full package.json:
{
"name": "${{ values.name }}",
"version": "1.0.0",
"description": "Microservice: ${{ values.name }}",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"dev": "node --watch src/index.js"
}
}
Here is the full src/index.js:
const http = require('http');
const PORT = process.env.PORT || 3001;
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
service: '${{ values.name }}',
status: 'healthy',
timestamp: new Date().toISOString()
}));
});
server.listen(PORT, () => {
console.log(`${{ values.name }} running on port ${PORT}`);
});
Here is the full skeleton catalog-info.yaml:
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: ${{ values.name }}
description: Microservice - ${{ values.name }}
spec:
type: service
lifecycle: experimental
owner: ${{ values.owner }}
Register the template and test it
Backstage discovers templates the same way it discovers catalog entities: through locations in app-config.yaml. You need to add your template's location so Backstage loads it on startup.
- Open app-config.yaml in the root of your my-portal directory.
- Find the catalog.locations section. You should see the entry you added in the previous step:
- type: file
target: ../../my-service/catalog-info.yaml
rules:
- allow: [Component]
- Add the following entry directly below it (at the same indentation level):
- type: file
target: templates/node-service/template.yaml
rules:
- allow: [Template]
What does this code do?
This tells Backstage to load your template.yaml as a catalog entity. The rules: - allow: [Template] line permits the file to register a Template kind entity (by default, only Components are allowed).
- Save app-config.yaml.
✔️ Awesome, I've got everything!
Great. Your catalog.locations section should now have two entries: one for your component and one for your template.
ⓧ I'd like to double check the full code
Your catalog.locations section in app-config.yaml should look like this:
catalog:
locations:
- type: file
target: ../../my-service/catalog-info.yaml
rules:
- allow: [Component]
- type: file
target: templates/node-service/template.yaml
rules:
- allow: [Template]
Now restart Backstage so it picks up the new template.
- Switch to the terminal tab where yarn start is running.
- Press Ctrl+C to stop the running process.
- Restart the app by running:
yarn start
- Wait for the Rspack compiled successfully message in your terminal.
- Open http://localhost:3000/create in your browser.
You should see your Node.js Microservice template card on the /create page alongside any demo templates.
Don't see your template?
Check that the target path in app-config.yaml is templates/node-service/template.yaml (not template/ without the s). Also verify the rules array says allow: [Template] with a capital T.
If the template still does not appear, check your terminal for YAML parse errors. The most common issue is incorrect indentation in template.yaml.
Help me troubleshoot why my Backstage template isn't showing up.
Time to run the template and see your scaffolder in action.
- Click the Choose button on your Node.js Microservice template card.
- In the Service Name field, enter order-processor.
- In the Owner field, enter team-commerce.
- Click Review to see a summary of your inputs.
- Click Create to run the template.
You should see a task log showing the Fetch Base step completing successfully with a green checkmark. The scaffolder has rendered your skeleton files with order-processor and team-commerce replacing the ${{ values.* }} placeholders.
What just happened?
The fetch:template action copied every file from your template/ directory into a workspace. It scanned each file for ${{ values.name }} and ${{ values.owner }} and replaced them with the values you entered in the form.
The generated package.json now says "name": "order-processor" and the catalog-info.yaml says owner: team-commerce. This is how platform teams enforce consistency across hundreds of services.
Seeing a template execution error?
If the task log shows a red error, expand the failed step to read the error message. The most common causes are a missing template/ directory (the url: ./template path in your step needs to resolve to the skeleton folder) or a syntax error in one of the skeleton files.
Help me debug my Backstage template execution error.
You've built a working Software Template from scratch. Any developer on your team can now spin up a fully configured Node.js microservice in seconds, with consistent structure, a health endpoint, and catalog registration baked in. Next, put your skills to the test with a bonus challenge.
Secret mission
Create a Documentation Site Template
Your node-service template gives teams a golden path for creating microservices. But what about documentation? In this mission, you'll build a second template that scaffolds a docs-as-code project with TechDocs integration.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely on your local machine, so there are no ongoing cloud costs or subscription charges. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- The my-portal directory (your Backstage app, templates, and configuration).
- The ~/my-service directory (your custom catalog component).
- Node.js 22 (installed via nvm).
- nvm (Node Version Manager).
Keep everything running
No action needed. Choose this if you're still actively building on your Backstage portal or plan to continue experimenting with templates and catalog entries.
- Your Backstage app will stay in the my-portal folder on your Desktop, ready to start anytime with yarn start.
- Node.js 22 and nvm will remain installed for future Node.js projects.
Pause - I'll come back to this later
Stop the running Backstage processes to free up system resources. Your files stay on disk so you can resume later.
- Switch to the terminal where Backstage is running.
- Press Ctrl+C to stop the frontend and backend processes.
- To restart later, navigate back to the my-portal directory and run yarn start.
Delete - I don't want to use this again
Remove all project files and optionally uninstall Node.js. This frees up disk space and leaves your system clean.
- Stop Backstage by pressing Ctrl+C in the terminal where it is running.
- Delete the Backstage project directory by running:
cd ~/Desktop
rm -rf my-portal
- Delete the custom service directory by running:
rm -rf ~/my-service
- (Optional) Uninstall Node.js 22 via nvm by running:
nvm uninstall 22
- (Optional) Remove nvm itself by running:
rm -rf "$NVM_DIR"
After removing nvm, edit your shell configuration file (~/.bashrc or ~/.zshrc) and delete the lines that load nvm.
Nice Work!
Nice Work!
You just built your first internal developer portal with Backstage. You now have a running local instance with a custom catalog entry and a reusable Software Template that scaffolds new projects through a guided form.
You've learned how to:
- Registered a custom service in the Software Catalog with ownership metadata using a catalog-info.yaml entity descriptor.
- Built a Software Template that scaffolds new Node.js microservice projects through a guided form using the fetch:template action.
- Configured app-config.yaml to register static catalog locations for both components and templates.
- Secret Mission: Created a Documentation Site template with TechDocs integration that scaffolds a docs-as-code project with mkdocs.yml configuration.
Ready to quiz yourself?