> ## Documentation Index
> Fetch the complete documentation index at: https://backstage.spotify.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Get started

> Set up a workspace to create, develop, and test custom plugins for Portal.

Custom Portal plugins are developed as Backstage packages in a local workspace. During development, you need a way to create those packages, run the development tooling, and test changes against a Portal instance.

Portal Studio provides a streamlined workflow for this. It can create a minimal plugin workspace or connect an existing repository to Portal, so you can build and test changes without maintaining a separate local Backstage application.

This guide shows how to use Portal Studio to get a plugin running in Portal, then covers existing workspaces, development workflows, testing, migration, configuration, troubleshooting, and advanced usage.

## Prerequisites

Before you start, make sure you have:

* Access to a Portal instance
* [Node.js](https://nodejs.org/) 24.x
* Yarn, enabled through [Corepack](https://yarnpkg.com/corepack)
* [React Developer Tools](https://react.dev/learn/react-developer-tools), which Studio uses for React Refresh

Enable Corepack and verify your tools:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
corepack enable
node --version
yarn --version
```

<Info>
  Portal plugins must use Backstage's [new frontend
  system](https://backstage.io/docs/frontend-system/) and [new backend
  system](https://backstage.io/docs/backend-system/).
</Info>

## Create a new Studio workspace

The Portal CLI can create a minimal workspace that is configured for plugin development against your Portal instance.

1. Create and enter an empty directory:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
mkdir my-portal-plugins
cd my-portal-plugins
```

2. Initialize the workspace:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
npx @spotify/portal-cli@latest studio init --instance <your-instance>
```

`<your-instance>` can be an instance name, such as `acme`, or a full URL, such as `https://portal.acme.org`. If you omit `--instance`, the CLI prompts you for it. Use `--skip-install` if you want to install dependencies separately.

The generated workspace includes the Portal CLI, Backstage plugin templates, local configuration, and scripts for common development tasks.

3. Create your first plugin or module:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
yarn new
```

The command opens an interactive prompt. To get started with a UI plugin, select the frontend plugin template. The generated package is added to the `plugins/` directory.

4. Start Portal Studio:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
yarn start
```

Studio detects the features in your workspace, starts the local development server, prints a Bootstrap URL, and normally opens it in your browser. Opening that URL activates Studio Mode in your Portal instance.

5. Make a change in the generated plugin and save the file. The frontend reloads in Portal so you can verify the change against your real Portal data and configuration.

<Tip>
  Use the floating **Studio mode** control in Portal to inspect active frontend
  and backend features, pause local overrides, or exit Studio Mode.
</Tip>

## Use Studio with an existing workspace

Portal Studio also works with an existing Backstage workspace or plugin repository. Install the repository's dependencies, then run Studio from its root:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
cd path/to/your-workspace
yarn install
npx @spotify/portal-cli@latest studio start --instance <your-instance>
```

Without additional arguments, Studio scans the workspace and starts all compatible plugin features it finds.

To limit a large workspace, pass package names or paths:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
npx @spotify/portal-cli@latest studio start \
  --instance <your-instance> \
  plugins/my-frontend-plugin \
  plugins/my-backend-plugin
```

You can also select features by plugin ID. Repeat `--plugin` to include more than one:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
npx @spotify/portal-cli@latest studio start \
  --instance <your-instance> \
  --plugin my-plugin \
  --plugin another-plugin
```

<Note>
  If you intentionally need to develop against a standalone open-source
  Backstage application, follow the [Backstage getting started
  documentation](https://backstage.io/docs/getting-started/). Portal customers
  do not need to create a Backstage application to develop or test plugins.
</Note>

## Understand plugins and modules

Portal and Backstage plugins are composed of npm packages. A plugin can contain separate packages for frontend React code, backend Node.js code, and code shared between them. This follows the [Backstage package structure](https://backstage.io/docs/architecture-decisions/adrs-adr011/).

Plugins connect to Backstage through its frontend and backend plugin systems. For example, a backend plugin package typically exports a feature created with `createBackendPlugin`.

A **module** extends another plugin rather than providing a standalone feature. For example, a module can add a software catalog provider, a scaffolder action, or a Soundcheck fact collector. Modules use [extension points](https://backstage.io/docs/backend-system/architecture/extension-points/) and must be installed alongside the plugin they extend.

The most common templates available through `yarn new` are:

* **Frontend plugin** - Adds pages, cards, navigation items, or other user interface extensions.
* **Backend plugin** - Adds APIs, services, scheduled tasks, or other server-side functionality.
* **Backend module** - Extends an existing backend plugin, such as the catalog or Soundcheck.
* **Frontend module** - Contributes extensions to an existing frontend plugin.

## Develop your plugin

### Frontend plugins

Frontend plugins must use the [new frontend system](https://backstage.io/docs/frontend-system/) to run in Portal Studio. Use [extension blueprints](https://backstage.io/docs/frontend-system/building-plugins/common-extension-blueprints) to add pages, navigation items, entity content, APIs, and other extensions.

A typical workflow is:

1. Create the package with `yarn new`.
2. Start Studio with `yarn start`.
3. Open the Bootstrap URL if it did not open automatically.
4. Edit the plugin in your local workspace.
5. Verify each saved change in Portal.

For plugin APIs and patterns, see the [Backstage frontend plugin guide](https://backstage.io/docs/frontend-system/building-plugins/).

### Backend plugins

Backend plugins must use the [new backend system](https://backstage.io/docs/backend-system/). When Studio detects backend features, it starts a local Studio backend and routes requests for those plugin APIs from Portal to your local services.

Your Portal user token is forwarded to the local Studio backend so that local services can authenticate as you. Requests that do not target a local Studio backend and are not clearly read-only can require confirmation while Studio Mode is active.

For plugin APIs and patterns, see the [Backstage backend plugin guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/).

### Backend modules

Backend modules extend an existing plugin through its extension points. For example, you can create:

* A software catalog entity provider
* A custom scaffolder action
* A search collator
* A [Soundcheck fact collector](/plugins/soundcheck/tutorials/custom-fact-collector)

Create a module with `yarn new`, choose a backend module template, and select the plugin that the module extends.

## Test your plugin

Studio lets you test local features with your Portal instance's catalog, configuration, integrations, and permissions.

The generated workspace provides these checks:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
# Fast type checking
yarn tsc

# Unit tests in watch mode
yarn test

# All unit tests with coverage
yarn test:all

# Lint the entire workspace
yarn lint:all

# Build all packages
yarn build:all
```

Existing repositories can use different script names. Follow the repository's own test and build instructions when they differ.

Use your browser's developer tools to inspect frontend logs and network requests. Keep the Studio terminal visible for compilation errors, backend logs, and catalog processing errors.

## Migrate an existing plugin to Portal

An existing Backstage plugin can run in Portal when its packages are compatible with the systems that Portal uses.

Before loading it in Studio:

1. Migrate frontend packages to the [new frontend system](https://backstage.io/docs/frontend-system/building-plugins/migrating/).
2. Migrate backend packages to the [new backend system](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/).
3. Make sure each package has a valid [Backstage package role](https://backstage.io/docs/tooling/cli/build-system/#package-roles) and that plugin packages define `backstage.pluginId` in `package.json`.
4. Run the repository's type checks and tests.
5. Start Portal Studio from the repository root and validate the migrated features in Portal.

If Studio reports that no features were detected, review its warnings. In repositories that use the Backstage CLI repository tooling, `yarn fix --publish` can populate missing package metadata.

## Publish and install your plugin

Studio is for local development and validation. When the plugin is ready:

1. Run the workspace's type checks, tests, and build.
2. Follow [Publishing Plugins](./publishing-plugins) to publish the packages.
3. Follow [Installing a Plugin](/portal/managing-plugins/installing-plugins) to install the package names in Portal.
4. Test the installed version before making it broadly available.

## Configure local backends

Local backend plugins use the standard Backstage configuration system. Put local values in `app-config.local.yaml` or another [supported configuration file](https://backstage.io/docs/conf/writing/).

Do not commit secrets. Use the configuration and secret-management practices established for your repository.

## Troubleshooting

### Studio does not open Portal

Studio normally opens the Bootstrap URL automatically. If it does not, copy the complete URL printed in the terminal and open it in your browser.

For environments where the CLI should not open a browser, run the command directly with `--no-open`:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
npx @spotify/portal-cli@latest studio start \
  --instance <your-instance> \
  --no-open
```

### Changes do not appear

* Confirm that you opened the exact Bootstrap URL from the current Studio session.
* Install and enable React Developer Tools.
* Check the terminal for compilation errors and warnings.
* Check the browser console for runtime errors.
* Restart Studio after dependency or package metadata changes.

### No features are detected

* Make sure you ran Studio from the workspace root.
* Install the workspace dependencies.
* Confirm that packages declare valid Backstage roles and `backstage.pluginId`.
* Review warnings printed by Studio.
* If the repository uses Backstage CLI repository tooling, run `yarn fix --publish`.
* Use package paths or `--plugin` to check whether Studio can discover a smaller selection.

### A backend plugin does not start or receive requests

* Confirm that the backend package is included in the detected feature list printed by Studio.
* Check the terminal for startup and configuration errors.
* Confirm that the plugin uses the new backend system.
* Verify values required by the plugin in your local Backstage configuration.

### Large workspaces start slowly

Pass only the package paths or plugin IDs that you are actively developing:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
npx @spotify/portal-cli@latest studio start \
  --instance <your-instance> \
  --plugin my-plugin
```

## Advanced usage

### Switch Portal instances

Both `studio init` and `studio start` accept an instance name or full URL through `--instance`. You can also set the `PORTAL_INSTANCE` environment variable:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
PORTAL_INSTANCE=staging \
  npx @spotify/portal-cli@latest studio start
```

### Start a local software catalog

If the workspace includes `@backstage/plugin-catalog-backend`, add `--with-catalog` to start Studio with a local catalog:

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
npx @spotify/portal-cli@latest studio start \
  --instance <your-instance> \
  --with-catalog
```

### Studio safety controls

While Studio Mode is active:

* Read-only requests can continue without confirmation.
* Write requests that would reach your Portal instance can require explicit approval.
* Requests for active local backend plugins are routed to your local Studio backend.
* The floating **Studio mode** control can pause overrides without ending the session.

## Sample plugins

These repositories contain plugins that use the frontend or backend systems required by Portal:

* [GitHub Actions](https://github.com/backstage/community-plugins/tree/main/workspaces/github-actions/plugins/github-actions)
* [Grafana](https://github.com/backstage/community-plugins/tree/main/workspaces/grafana)
* [Jenkins](https://github.com/backstage/community-plugins/tree/main/workspaces/jenkins)
* [Kubernetes frontend](https://github.com/backstage/backstage/tree/master/plugins/kubernetes)
* [Kubernetes backend](https://github.com/backstage/backstage/tree/master/plugins/kubernetes-backend)

You can run Portal Studio in a compatible existing workspace and select only the plugin packages that you want to load.

## Get help

If the troubleshooting guidance does not resolve the issue:

1. Review errors in the Studio terminal.
2. Review the browser console and network requests.
3. [Contact Spotify Support](https://backstage.spotify.com/account/support/).
