diff --git a/.changeset/add-badge-component.md b/.changeset/add-badge-component.md
new file mode 100644
index 0000000000..5f07272a44
--- /dev/null
+++ b/.changeset/add-badge-component.md
@@ -0,0 +1,7 @@
+---
+'@backstage/ui': patch
+---
+
+Added new `Badge` component for non-interactive labeling and categorization of content. It shares the visual appearance of `Tag` but renders as a plain DOM element with no interactive states.
+
+**Affected components:** Badge
diff --git a/docs-ui/src/app/components/badge/components.tsx b/docs-ui/src/app/components/badge/components.tsx
new file mode 100644
index 0000000000..a77a6b09d7
--- /dev/null
+++ b/docs-ui/src/app/components/badge/components.tsx
@@ -0,0 +1,16 @@
+'use client';
+
+import { Badge } from '../../../../../packages/ui/src/components/Badge/Badge';
+import { Flex } from '../../../../../packages/ui/src/components/Flex/Flex';
+import { RiBugLine } from '@remixicon/react';
+
+export const Default = () => Banana;
+
+export const WithIcon = () => }>Banana;
+
+export const Sizes = () => (
+
+ Banana
+ Banana
+
+);
diff --git a/docs-ui/src/app/components/badge/page.mdx b/docs-ui/src/app/components/badge/page.mdx
new file mode 100644
index 0000000000..fb934c57ad
--- /dev/null
+++ b/docs-ui/src/app/components/badge/page.mdx
@@ -0,0 +1,41 @@
+import { PropsTable } from '@/components/PropsTable';
+import { Snippet } from '@/components/Snippet';
+import { CodeBlock } from '@/components/CodeBlock';
+import { Default, WithIcon, Sizes } from './components';
+import { badgePropDefs } from './props-definition';
+import { usage, preview, withIcons, sizes } from './snippets';
+import { PageTitle } from '@/components/PageTitle';
+import { Theming } from '@/components/Theming';
+import { BadgeDefinition } from '../../../utils/definitions';
+import { ChangelogComponent } from '@/components/ChangelogComponent';
+
+
+
+} code={preview} />
+
+## Usage
+
+
+
+## API reference
+
+### Badge
+
+
+
+## Examples
+
+### With icons
+
+} code={withIcons} />
+
+### Sizes
+
+} code={sizes} />
+
+
+
+
diff --git a/docs-ui/src/app/components/badge/props-definition.tsx b/docs-ui/src/app/components/badge/props-definition.tsx
new file mode 100644
index 0000000000..b193c1cef2
--- /dev/null
+++ b/docs-ui/src/app/components/badge/props-definition.tsx
@@ -0,0 +1,27 @@
+import {
+ classNamePropDefs,
+ childrenPropDefs,
+ type PropDef,
+} from '@/utils/propDefs';
+import { Chip } from '@/components/Chip';
+
+export const badgePropDefs: Record = {
+ icon: {
+ type: 'enum',
+ values: ['ReactNode'],
+ description: 'Icon displayed before the badge text.',
+ },
+ size: {
+ type: 'enum',
+ values: ['small', 'medium'],
+ default: 'small',
+ description: (
+ <>
+ Visual size of the badge. Use small for inline or dense
+ layouts, medium for standalone badges.
+ >
+ ),
+ },
+ ...childrenPropDefs,
+ ...classNamePropDefs,
+};
diff --git a/docs-ui/src/app/components/badge/snippets.ts b/docs-ui/src/app/components/badge/snippets.ts
new file mode 100644
index 0000000000..dc765d2b7d
--- /dev/null
+++ b/docs-ui/src/app/components/badge/snippets.ts
@@ -0,0 +1,12 @@
+export const usage = `import { Badge } from '@backstage/ui';
+
+Badge`;
+
+export const preview = `Banana`;
+
+export const withIcons = `}>Banana`;
+
+export const sizes = `
+ Banana
+ Banana
+`;
diff --git a/docs-ui/src/utils/data.ts b/docs-ui/src/utils/data.ts
index bd37760ea4..3d958f5b7c 100644
--- a/docs-ui/src/utils/data.ts
+++ b/docs-ui/src/utils/data.ts
@@ -17,6 +17,10 @@ export const components: Page[] = [
title: 'Avatar',
slug: 'avatar',
},
+ {
+ title: 'Badge',
+ slug: 'badge',
+ },
{
title: 'Box',
slug: 'box',
diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md
index 093d18e707..a2588e22de 100644
--- a/packages/ui/report.api.md
+++ b/packages/ui/report.api.md
@@ -318,6 +318,45 @@ export interface AvatarProps
extends Omit, 'children' | 'className'>,
AvatarOwnProps {}
+// @public
+export const Badge: ForwardRefExoticComponent<
+ BadgeProps & RefAttributes
+>;
+
+// @public
+export const BadgeDefinition: {
+ readonly styles: {
+ readonly [key: string]: string;
+ };
+ readonly classNames: {
+ readonly root: 'bui-Badge';
+ readonly icon: 'bui-BadgeIcon';
+ };
+ readonly bg: 'consumer';
+ readonly propDefs: {
+ readonly icon: {};
+ readonly size: {
+ readonly dataAttribute: true;
+ readonly default: 'small';
+ };
+ readonly children: {};
+ readonly className: {};
+ };
+};
+
+// @public
+export type BadgeOwnProps = {
+ icon?: React.ReactNode;
+ size?: 'small' | 'medium';
+ children?: React.ReactNode;
+ className?: string;
+};
+
+// @public
+export interface BadgeProps
+ extends BadgeOwnProps,
+ Omit, keyof BadgeOwnProps> {}
+
// @public (undocumented)
export interface BgContextValue {
// (undocumented)
diff --git a/packages/ui/src/components/Badge/Badge.module.css b/packages/ui/src/components/Badge/Badge.module.css
new file mode 100644
index 0000000000..ec985161ca
--- /dev/null
+++ b/packages/ui/src/components/Badge/Badge.module.css
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2025 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@layer tokens, base, components, utilities;
+
+@layer components {
+ .bui-Badge {
+ color: var(--bui-fg-primary);
+ background-color: var(--bui-bg-neutral-1);
+ border-radius: var(--bui-radius-2);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: var(--bui-font-weight-regular);
+ gap: var(--bui-space-1);
+
+ &[data-on-bg='neutral-1'] {
+ background-color: var(--bui-bg-neutral-2);
+ }
+
+ &[data-on-bg='neutral-2'] {
+ background-color: var(--bui-bg-neutral-3);
+ }
+
+ &[data-on-bg='neutral-3'] {
+ background-color: var(--bui-bg-neutral-4);
+ }
+ }
+
+ .bui-Badge[data-size='small'] {
+ height: 26px;
+ padding: 0 var(--bui-space-2);
+ font-size: var(--bui-font-size-1);
+ }
+
+ .bui-Badge[data-size='medium'] {
+ height: 32px;
+ padding: 0 var(--bui-space-2);
+ font-size: var(--bui-font-size-2);
+ }
+
+ .bui-BadgeIcon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ svg {
+ width: 1rem;
+ height: 1rem;
+ }
+ }
+}
diff --git a/packages/ui/src/components/Badge/Badge.stories.tsx b/packages/ui/src/components/Badge/Badge.stories.tsx
new file mode 100644
index 0000000000..9e5604b263
--- /dev/null
+++ b/packages/ui/src/components/Badge/Badge.stories.tsx
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2025 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import preview from '../../../../../.storybook/preview';
+import { Badge } from '.';
+import { Flex } from '../../';
+import { BUIProvider } from '../../provider';
+import { RiBugLine } from '@remixicon/react';
+
+const meta = preview.meta({
+ title: 'Backstage UI/Badge',
+ component: Badge,
+ decorators: [
+ Story => (
+
+
+
+ ),
+ ],
+});
+
+export const Default = meta.story({
+ args: {
+ children: 'Banana',
+ },
+});
+
+export const Sizes = meta.story({
+ render: () => (
+
+ Banana
+ Banana
+
+ ),
+});
+
+export const WithIcon = meta.story({
+ render: () => (
+
+ }>
+ Banana
+
+ }>
+ Banana
+
+
+ ),
+});
diff --git a/packages/ui/src/components/Badge/Badge.tsx b/packages/ui/src/components/Badge/Badge.tsx
new file mode 100644
index 0000000000..f5b8e5918b
--- /dev/null
+++ b/packages/ui/src/components/Badge/Badge.tsx
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2025 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { BadgeProps } from './types';
+import { forwardRef } from 'react';
+import { useDefinition } from '../../hooks/useDefinition';
+import { BadgeDefinition } from './definition';
+
+/**
+ * A non-interactive badge for labeling or categorizing content.
+ *
+ * @public
+ */
+export const Badge = forwardRef((props, ref) => {
+ const { ownProps, restProps, dataAttributes } = useDefinition(
+ BadgeDefinition,
+ props,
+ );
+ const { classes, children, icon } = ownProps;
+
+ return (
+
+ {icon && {icon}}
+ {children}
+
+ );
+});
diff --git a/packages/ui/src/components/Badge/definition.ts b/packages/ui/src/components/Badge/definition.ts
new file mode 100644
index 0000000000..cba0daeb8e
--- /dev/null
+++ b/packages/ui/src/components/Badge/definition.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2025 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from '../../hooks/useDefinition';
+import type { BadgeOwnProps } from './types';
+import styles from './Badge.module.css';
+
+/**
+ * Component definition for Badge
+ * @public
+ */
+export const BadgeDefinition = defineComponent()({
+ styles,
+ classNames: {
+ root: 'bui-Badge',
+ icon: 'bui-BadgeIcon',
+ },
+ bg: 'consumer',
+ propDefs: {
+ icon: {},
+ size: { dataAttribute: true, default: 'small' },
+ children: {},
+ className: {},
+ },
+});
diff --git a/packages/ui/src/components/Badge/index.ts b/packages/ui/src/components/Badge/index.ts
new file mode 100644
index 0000000000..0041936187
--- /dev/null
+++ b/packages/ui/src/components/Badge/index.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2025 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { Badge } from './Badge';
+export type { BadgeProps, BadgeOwnProps } from './types';
+export { BadgeDefinition } from './definition';
diff --git a/packages/ui/src/components/Badge/types.ts b/packages/ui/src/components/Badge/types.ts
new file mode 100644
index 0000000000..e22c0eb345
--- /dev/null
+++ b/packages/ui/src/components/Badge/types.ts
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2025 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Own props for the Badge component.
+ *
+ * @public
+ */
+export type BadgeOwnProps = {
+ /**
+ * The icon to display before the badge text.
+ */
+ icon?: React.ReactNode;
+ /**
+ * The size of the badge.
+ */
+ size?: 'small' | 'medium';
+ children?: React.ReactNode;
+ className?: string;
+};
+
+/**
+ * Props for the Badge component.
+ *
+ * @public
+ */
+export interface BadgeProps
+ extends BadgeOwnProps,
+ Omit, keyof BadgeOwnProps> {}
diff --git a/packages/ui/src/definitions.ts b/packages/ui/src/definitions.ts
index d90437376e..3cc94e1cde 100644
--- a/packages/ui/src/definitions.ts
+++ b/packages/ui/src/definitions.ts
@@ -27,6 +27,7 @@ export {
} from './components/Accordion/definition';
export { AlertDefinition } from './components/Alert/definition';
export { AvatarDefinition } from './components/Avatar/definition';
+export { BadgeDefinition } from './components/Badge/definition';
export { BoxDefinition } from './components/Box/definition';
export { ButtonDefinition } from './components/Button/definition';
export { ButtonIconDefinition } from './components/ButtonIcon/definition';
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index abf4b4accb..464df3a845 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -31,6 +31,7 @@ export * from './components/FullPage';
export * from './components/Accordion';
export * from './components/Alert';
export * from './components/Avatar';
+export * from './components/Badge';
export * from './components/Button';
export * from './components/Card';
export * from './components/Dialog';