Bazaar logo

Backstage Bazaar Plugin

Created by Axis Communications AB

Bazaar brings inner source to Backstage. It gives your teams a shared place to propose work, discover needs, and join forces across org lines. Think of it as an internal project marketplace that follows open source style workflows. Engineers can surface ideas, describe the problem, and ask for skills. Others can register interest and join when it fits.

The plugin adds a page in Backstage with cards for each project. Cards show a summary, status, size, contact, and links to docs or chat. You can search, sort by name or members, and link a project to an existing catalog entity. When a project is linked, its info can appear on the entity page. This makes it easier to find the right work at the right time. It helps teams share ownership of refactors, migrations, tooling upgrades, and spikes that need more hands.

Bazaar was created by Axis Communications. They build on Backstage in their own platform work and contribute plugins to the community.

Installation Instructions

These instructions apply to self-hosted Backstage only.

Install the frontend package

Copy
yarn --cwd packages/app add @backstage-community/plugin-bazaar

Add the Bazaar page route

Edit packages/app/src/App.tsx

Copy
// packages/app/src/App.tsx
import React from 'react';
import { Route } from 'react-router';
import { FlatRoutes } from '@backstage/core-app-api';
import { BazaarPage } from '@backstage-community/plugin-bazaar';

export const App = () => (
  <FlatRoutes>
    {/* other routes */}
    <Route path="bazaar" element={<BazaarPage />} />
  </FlatRoutes>
);

Optional props on BazaarPage

Copy
<Route
  path="bazaar"
  element={<BazaarPage fullHeight fullWidth />}
/>

Add a sidebar item

Edit packages/app/src/components/Root.tsx

Copy
// packages/app/src/components/Root.tsx
import React from 'react';
import { SidebarItem, SidebarDivider, SidebarScrollWrapper } from '@backstage/core-components';
import StorefrontIcon from '@material-ui/icons/Storefront';

export const Root = ({ children }: { children?: React.ReactNode }) => (
  <>
    {/* other sidebar parts */}
    <SidebarDivider />
    <SidebarScrollWrapper>
      <SidebarItem icon={StorefrontIcon} to="bazaar" text="Bazaar" />
      {/* other sidebar items */}
    </SidebarScrollWrapper>
    {children}
  </>
);

Add the entity page card

Edit packages/app/src/components/catalog/EntityPage.tsx

Copy
// packages/app/src/components/catalog/EntityPage.tsx
import React from 'react';
import Grid from '@material-ui/core/Grid';
import { EntityAboutCard, EntitySwitch } from '@backstage/plugin-catalog';
import { EntityBazaarInfoCard, isBazaarAvailable } from '@backstage-community/plugin-bazaar';

export const overviewContent = (
  <>
    <Grid item md={8} xs={12}>
      <EntityAboutCard variant="gridItem" />
    </Grid>

    <EntitySwitch>
      <EntitySwitch.Case if={isBazaarAvailable}>
        <Grid item sm={6}>
          <EntityBazaarInfoCard />
        </Grid>
      </EntitySwitch.Case>
    </EntitySwitch>

    {/* other entity cards */}
  </>
);

Add homepage overview cards

Edit packages/app/src/components/home/HomePage.tsx

Copy
// packages/app/src/components/home/HomePage.tsx
import React from 'react';
import Grid from '@material-ui/core/Grid';
import { Page, Content } from '@backstage/core-components';
import { BazaarOverviewCard } from '@backstage-community/plugin-bazaar';

export const HomePage = () => (
  <Page themeId="home">
    <Content>
      <Grid container spacing={3}>
        <Grid item xs={12} md={6}>
          <BazaarOverviewCard order="latest" />
        </Grid>

        <Grid item xs={12}>
          <BazaarOverviewCard title="My Orgs Projects" order="random" fullWidth fullHeight />
        </Grid>

        {/* other homepage items */}
      </Grid>
    </Content>
  </Page>
);

Note on props

  • title is optional
  • fullHeight is optional
  • fullWidth is optional

Install the backend package

Copy
yarn --cwd packages/backend add @backstage-community/plugin-bazaar-backend

Wire the backend for the old backend system

Create a router file

Copy
// packages/backend/src/plugins/bazaar.ts
import { Router } from 'express';
import { CatalogClient } from '@backstage/catalog-client';
import { createRouter } from '@backstage-community/plugin-bazaar-backend';
import { PluginEnvironment } from '../types';

export default async function createPlugin(env: PluginEnvironment): Promise<Router> {
  const catalogClient = new CatalogClient({ discoveryApi: env.discovery });

  return await createRouter({
    logger: env.logger,
    database: env.database,
    catalogClient,
    identity: env.identity,
  });
}

Mount the router

Copy
// packages/backend/src/index.ts
import bazaar from './plugins/bazaar';

// inside the main bootstrap where you create plugin envs
const bazaarEnv = useHotMemoize(module, () => createEnv('bazaar'));

// after creating apiRouter
apiRouter.use('/bazaar', await bazaar(bazaarEnv));

Notes

  • This mounts the service at backend base path /bazaar
  • The plugin uses the app database through the plugin database manager

Wire the backend for the new backend system

Add the module to your backend builder

Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
import { bazaarPlugin } from '@backstage-community/plugin-bazaar-backend';

const backend = createBackend();

// register the Bazaar backend
backend.add(bazaarPlugin());

backend.start();

If your version exports a module factory named bazaarModule use that instead

Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
import { bazaarModule } from '@backstage-community/plugin-bazaar-backend';

const backend = createBackend();
backend.add(bazaarModule());
backend.start();

Common setup notes

  • No extra app config is usually required
  • The backend stores Bazaar data in your Backstage database
  • Make sure your backend has identity set up so users can join projects

Changelog

This changelog is produced from commits made to the Bazaar plugin since a year ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.

Features

  • Add user picker for the responsible field in create and edit flows. Keep free text as fallback. Link the value in the info card when it is an entity ref #1535 merged 11 months ago
  • Show next steps after a user joins a project. Hide this on the entity page card #1538 merged 11 months ago

Performance

  • Add virtualization to the UserSelector dropdown to handle large user lists smoothly #1747 merged 11 months ago

Developer experience

  • Improve yarn dev setup. Run frontend and backend together in dev. Use the real Bazaar API. Fix project card routes. Add the OverviewCard widget in dev #1514 merged 11 months ago

Deprecations

  • Use the new backend system by default for the Bazaar backend plugin. Export the backend plugin as default. Mark createRouter deprecated. Mark the alpha export deprecated. See the PR for install and migration notes #3017 merged 6 months ago

Maintenance

  • Remove unused canvas dev dependency #3565 merged 5 months ago
  • Reduce knip false positives by updating repo tools and using a workspace level config #3018 merged 6 months ago

Set up Backstage in minutes with Roadie