backstage-theming

backstage-theming is a skill for Claude Code from bendaamerahmed/backstage-idp-plugin. It costs 42 tokens per session (2,288 once invoked), scanned A, original, MIT.

A Backstage theming guide explains how to change the appearance of a Backstage developer portal. It covers newer design tokens and older Material UI themes, which are two styling systems used together.

In plain words
What is it for?
Use it to customise colours, light and dark themes, branding, logos, design tokens, and component definitions in a Backstage app.
Why use it?
It helps prevent changes from affecting only part of the portal because the wrong styling system was edited.

Skill for Claude Code

Written for Claude Code: when-to-use in frontmatter.

Part of the backstage-idp plugin — 15 skills, 1 agent shipped together

Good fit Use it to customise colours, light and dark themes, branding, logos, design tokens, and component definitions in a Backstage app.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/bendaamerahmed/backstage-idp-plugin/backstage-theming
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add bendaamerahmed/backstage-idp-plugin --skill backstage-theming
Clone the repo
git clone --depth 1 https://github.com/bendaamerahmed/backstage-idp-plugin

Made for: Claude Code.

Or install backstage-idp, the plugin that ships this one along with the rest of its 15 skills, 1 agent.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for backstage-theming

README.md
[![agentmods](https://agentmods.dev/badge/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming/github.svg)](https://agentmods.dev/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming)
Your own site
<a href="https://agentmods.dev/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming"><img src="https://agentmods.dev/badge/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for backstage-theming

Your own site · 80×15
<a href="https://agentmods.dev/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming"><img src="https://agentmods.dev/badge/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 42 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,288 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00042 $0.02288
Opus 5 $0.00021 $0.01144
Sonnet 5 $0.00008 $0.00458
Haiku 4.5 $0.00004 $0.00229

Measured 10d ago against content hash faaffd15b35d, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-11, from the pricing page.

Security

Grade A, and why

backstage-theming scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 10d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

plugins/backstage-idp/skills/backstage-theming/SKILL.md · 151 lines

How it starts

The opening of the file, as written. The whole thing — 151 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Backstage theming and design

Two theme systems run side by side in a current Backstage app, and most theming bugs are one of them being styled while the other is not. Decide which surface you are changing before you change anything.

Preconditions

  • Frontend generation known. NFS: createApp from @backstage/frontend-defaults, themes registered as extensions via ThemeBlueprint from @backstage/plugin-app-react. Legacy: createApp from @backstage/app-defaults with a themes array option. The theme objects are nearly identical; only registration differs. Run backstage-repo-discovery if unsure.
  • Which system owns the pixels you are changing:
    • @backstage/ui ("BUI") — CSS custom properties, --bui-*. Newer surfaces: entity cards, headers, tables, form controls.
    • @backstage/theme + Material UI — a JS theme object. Older plugin pages and every third-party plugin that has not migrated. A portal on a current line contains both. Styling one and declaring victory is the single most common outcome here.
  • packages/app/src/index.tsx imports @backstage/ui/css/styles.css. Without it no BUI token has a value and every BUI component renders unstyled.
  • Exact theme factory signatures (createUnifiedTheme, createBaseThemeOptions, genPageTheme, and the ThemeBlueprint input shape) read from the installed @backstage/theme and @backstage/plugin-app-react types, not from memory.
  • Brand assets available as real files. Do not invent colour values; ask for the brand tokens or read them from an existing asset, and record the source.

Procedure

  1. Inventory what is themed today. rg -n "createUnifiedTheme|UnifiedThemeProvider|ThemeBlueprint|themes:" packages/app/src and rg -n "\-\-bui-" packages plugins. Note whether a custom theme exists at all — a default create-app has none, and adding the first one is a different job from editing an existing one.
  2. Change BUI tokens first, in one place. Override the custom properties on :root in a stylesheet imported after @backstage/ui/css/styles.css. The families are --bui-bg-*, --bui-fg-*, --bui-gray-*, --bui-accent-*, --bui-border-*, --bui-radius-*, --bui-font-*, --bui-space-*, plus the status families --bui-positive-*, --bui-negative-*, --bui-warning-* and --bui-announcement-*. Read the shipped dist/css/styles.css in the installed @backstage/ui for the exact names on your version; they are added to between minors.
  3. Do light and dark together or neither. BUI scopes its palette with a data-theme attribute on a root element. An override written only against :root leaks the light value into dark mode, which looks like "dark mode is broken" and is really a missing scoped override. Set every colour token under both selectors.
  4. Then the Material UI side. createUnifiedTheme from @backstage/theme produces a theme both v4 and v5 consumers can use; createUnifiedThemeFromV4 adapts an existing v4 theme rather than rewriting it. Compose from createBaseThemeOptions and palettes.light / palettes.dark instead of building a palette by hand — the defaults carry the page gradients and status colours plugins expect to exist.
  5. Set page themes deliberately. genPageTheme({ colors, shape }) builds the header gradient per page type (home, tool, service, website, library, app, apis, documentation, other). Omitting a page type leaves it on the default, which is the usual cause of "one page still has the old header".
  6. Register the theme for your generation.
    • NFS: create a theme extension with ThemeBlueprint from @backstage/plugin-app-react and add it to a frontend module. Read the blueprint's parameter names from the installed package before writing it.
    • Legacy: pass themes: [{ id, title, variant, icon, Provider }] to createApp, with Provider rendering UnifiedThemeProvider. Registering a theme does not select it: users pick per account in settings, so verify by switching, not by loading the page once.
  7. Keep BUIProvider in the tree, inside the router. It supplies the analytics context and, when it detects a router, installs react-aria's RouterProvider so BUI navigation resolves client-side. Outside the router it silently degrades to no routing integration.
  8. Override a component's look through its definition, not its internals. Each BUI component exports a <Name>Definition alongside it. Prefer a token change, then a definition override, then a wrapper component. Never target BUI's generated class names — they are not a public API and change without a major.
  9. Brand the app shell. Logos live in packages/app/src/modules/nav/ (LogoFull.tsx, LogoIcon.tsx, SidebarLogo.tsx) in a current scaffold. Replace the SVG contents, keep the components' exported names and their viewBox-driven sizing, and check the collapsed sidebar as well as expanded.
  10. Set app.title and organization.name in app-config.yaml. They drive the browser title and several page headers, and a rebrand that misses them leaves the old name in the tab.
  11. Check contrast before shipping. Brand colours frequently fail WCAG AA on Backstage's surfaces, particularly accent-on-surface for links and the status families. Fix the token, not the component.

Read the full file on GitHub · 151 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 10d ago First seen · 151 lines · 42 tokens per session scan A faaffd15b35d

Subscribe to this mod's changes

backstage-theming is a skill published in the GitHub repository bendaamerahmed/backstage-idp-plugin (1 stars, last pushed 1mo ago), licensed MIT. It adds 42 tokens to every session and 2,288 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other skills, from other repositories

shiny-bslib-theming

Advanced theming for Shiny apps using bslib and Bootstrap 5. Use when customizing app appearance with bstheme(), Bootswatch themes, custom colors, typography, brand.yml integration, Bootstrap Sass variables, custom Sass/CSS rules, dark mode and color modes, dynamic theme switching, real-time theming, theme inspection…

posit-dev/skills · 87 tokens

shiny-bslib

Build modern Shiny dashboards and applications using bslib (Bootstrap 5). Use when creating new Shiny apps, modernizing legacy apps (fluidPage, fluidRow/column, tabsetPanel, wellPanel, shinythemes), or working with bslib page layouts, grid systems, cards, value boxes, navigation, sidebars, filling layouts, theming…

posit-dev/skills · 107 tokens

interface-craft

Raises the visual and interaction quality of an interface — layout, hierarchy, type, spacing, density, and the details that separate a considered product from a generic one. Use this when a screen works but looks unfinished or default, when a layout feels crowded or arbitrary, when a page has no clear focal point, or…

cbrock84/headcount · 79 tokens

design-system

Builds and maintains the design system a product is assembled from — tokens for color, type, spacing and elevation, component contracts, and the rules that keep them coherent as the product grows. Use this when starting a new interface, when screens have drifted apart visually, when the same component exists three…

cbrock84/headcount · 82 tokens

interface-redesign

Upgrades an existing interface to a higher standard without rebuilding it — auditing what is there, identifying what reads as generic or unfinished, and sequencing changes by impact. Use this when a product works but looks dated or default, when a redesign is being considered, when deciding whether to restyle or…

cbrock84/headcount · 77 tokens

design-motion

Use when adding or reviewing motion on an already-settled layout or component — never to hide or compensate for an unfinished one.

fusengine/agents · 29 tokens