npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@alexandreamormino/plugin-entity-manager

v1.0.4

Published

Frontend plugin for managing Backstage catalog entities through a Monaco YAML editor

Readme

Entity Manager Frontend Plugin

Frontend plugin for creating and editing Backstage catalog entities through a YAML editor.

Installation

cd packages/app
yarn add @alexandreamormino/plugin-entity-manager

Replace the Catalog Import Page

Entity Manager can replace Backstage's default catalog import page while preserving the existing /catalog-import route and permission behavior.

Replace the default route:

<Route
  path="/catalog-import"
  element={
    <RequirePermission permission={catalogEntityCreatePermission}>
      <CatalogImportPage />
    </RequirePermission>
  }
/>

With:

<Route
  path="/catalog-import"
  element={
    <RequirePermission permission={catalogEntityCreatePermission}>
      <EntityManagerCreatePage />
    </RequirePermission>
  }
/>

After this change, users who access /catalog-import will see the Entity Manager creation page instead of the default Backstage catalog import page.

Remove the CatalogImportPage import from App.tsx when it is no longer used anywhere else in the application.

Configure Catalog External Routes

Locate the catalog external routes binding in packages/app/src/App.tsx:

bind(catalogPlugin.externalRoutes, {
  createComponent: scaffolderPlugin.routes.root,
  viewTechDoc: techdocsPlugin.routes.docRoot,
  createFromTemplate: scaffolderPlugin.routes.selectedTemplate,
});

Replace it with:

bind(catalogPlugin.externalRoutes, {
  createComponent: entityManagerPlugin.routes.root,
  viewTechDoc: techdocsPlugin.routes.docRoot,
  createFromTemplate: scaffolderPlugin.routes.selectedTemplate,
});

This redirects catalog actions that create entities from templates to the Entity Manager plugin.

Register the Entity Manager API

In packages/app/src/apis.ts, import the Entity Manager API factory:

import { entityManagerApiFactory } from '@alexandreamormino/plugin-entity-manager';

Add entityManagerApiFactory to the apis array:

export const apis: AnyApiFactory[] = [
  entityManagerApiFactory,
  createApiFactory({
    api: scmIntegrationsApiRef,
    deps: { configApi: configApiRef },
    factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi),
  }),
  ScmAuth.createDefaultApiFactory(),
];

This registers the Entity Manager API factory in the Backstage frontend application.

Replace Catalog Entity Components

In packages/app/src/components/catalog/EntityPage.tsx, replace the default Backstage components with the Entity Manager equivalents.

Add the imports:

import {
  EntityManagerAboutCard,
  EntityManagerLayout,
} from '@alexandreamormino/plugin-entity-manager';

Replace:

<EntityAboutCard />

With:

<EntityManagerAboutCard />

Replace:

<EntityLayout>
  {/* Entity page content */}
</EntityLayout>

With:

<EntityManagerLayout>
  {/* Entity page content */}
</EntityManagerLayout>

EntityManagerAboutCard is a drop-in replacement for EntityAboutCard.

  • Adds Edit and Delete actions for entities managed by Entity Manager
  • Renders the default Backstage entity card for all other entities

EntityManagerLayout is a drop-in replacement for EntityLayout.

  • Hides the Unregister entity option for entities managed by Entity Manager
  • Preserves the default layout behavior for all other entities

Custom button integration

If you want to build your own card or toolbar, you can use the buttons directly. They are re-exported from entity-manager-react so a separate install is not required.

import {
  EditEntityButton,
  DeleteEntityButton,
  isEntityManagerManaged,
} from '@alexandreamormino/plugin-entity-manager';
import { usePermission } from '@backstage/plugin-permission-react';
import {
  entityManagerUpdatePermission,
  entityManagerDeletePermission,
} from '@alexandreamormino/plugin-entity-manager-common';

const { allowed: canEdit } = usePermission({ permission: entityManagerUpdatePermission });
const { allowed: canDelete } = usePermission({ permission: entityManagerDeletePermission });

<EditEntityButton
  entityKind={entity.kind}
  entityName={entity.metadata.name}
  onLoadEntity={async () => {
    const { entity: loaded } = await api.getEntity(entity.kind, entity.metadata.name);
    return loaded;
  }}
  onSave={async (updated) => {
    await api.updateEntity(entity.kind, entity.metadata.name, updated);
  }}
  disabled={!canEdit}
  asIconButton
/>

<DeleteEntityButton
  entityKind={entity.kind}
  entityName={entity.metadata.name}
  onDelete={async () => {
    await api.deleteEntity(entity.kind, entity.metadata.name);
  }}
  disabled={!canDelete}
  asIconButton
/>

isEntityManagerManaged(entity) returns true when the entity's backstage.io/managed-by-location annotation starts with entity-manager-provider:.

Development

yarn workspace @alexandreamormino/plugin-entity-manager start
yarn workspace @alexandreamormino/plugin-entity-manager test
yarn workspace @alexandreamormino/plugin-entity-manager lint