XCMetrics is an open source tool from Spotify that collects and analyzes Xcode build logs. It parses xcactivitylog files to surface build times, warnings, errors, target compile times, and more. You run the backend yourself so the data stays under your control.
The XCMetrics Backstage plugin brings those metrics into your developer portal. It connects to your XCMetrics backend and presents a simple web view for teams. You get an overview of recent builds, trend charts, and ways to inspect details when something slows down. It is a quick way to make build health visible next to your catalogs, docs, and workflows.
Common use cases include tracking build times across projects, spotting slow targets before they hurt release cadence, watching warning growth, comparing CI and local builds, and checking the impact of Xcode upgrades or refactors. The data helps you plan fixes and verify results without leaving Backstage.
Spotify reports using XCMetrics at scale across its iOS apps. As their docs note, “XCMetrics has collected almost 1 million builds and over 10 billion steps from all Spotify iOS applications since its introduction.”
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the frontend package
yarn --cwd packages/app add @backstage-community/plugin-xcmetrics
Add the route in the app
Open packages/app/src/App.tsx. Import the page. Add a route.
// packages/app/src/App.tsx
import React from 'react';
import { Route } from 'react-router-dom';
import { FlatRoutes } from '@backstage/core-app-api';
import { XcmetricsPage } from '@backstage-community/plugin-xcmetrics';
export const App = () => {
return (
<FlatRoutes>
{/* other routes */}
<Route path="/xcmetrics" element={<XcmetricsPage />} />
</FlatRoutes>
);
};
Add a sidebar link
Open packages/app/src/components/Root/Root.tsx. Add a sidebar item that points to the page.
// packages/app/src/components/Root/Root.tsx
import React from 'react';
import { SidebarItem } from '@backstage/core-components';
import BarChartIcon from '@mui/icons-material/BarChart';
// find the Sidebar section and add this item among the others
<SidebarItem icon={BarChartIcon} to="/xcmetrics" text="XCMetrics" />
Set the proxy to your XCMetrics server
Add the proxy entry in app-config.yaml. Point it at your XCMetrics API.
# app-config.yaml
proxy:
'/xcmetrics':
target: http://127.0.0.1:8080/v1
Backend set up old backend system
If your backend already runs the proxy plugin, you only need the app config above. If not, add the proxy backend.
Add the package.
yarn --cwd packages/backend add @backstage/plugin-proxy-backend
Create the proxy router.
// packages/backend/src/plugins/proxy.ts
import { createRouter } from '@backstage/plugin-proxy-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
discovery: env.discovery,
tokenManager: env.tokenManager,
});
}
Wire it in the backend index.
// packages/backend/src/index.ts
import proxy from './plugins/proxy';
// inside the main bootstrap where apiRouter is created
const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
apiRouter.use('/proxy', await proxy(proxyEnv));
The frontend will call the path under api proxy which maps to the config you set.
Backend set up new backend system
If your backend already includes the proxy plugin, you only need the app config above. If not, add it.
Add the package.
yarn --cwd packages/backend add @backstage/plugin-proxy-backend
Register the proxy plugin.
// packages/backend/src/index.ts or packages/backend/src/main.ts
import { createBackend } from '@backstage/backend-defaults';
import { proxyPlugin } from '@backstage/plugin-proxy-backend';
const backend = createBackend();
backend.add(proxyPlugin());
backend.start();
What the plugin exports
The plugin exports a page component and a plugin instance.
import { XcmetricsPage, xcmetricsPlugin } from '@backstage-community/plugin-xcmetrics';
You use XcmetricsPage in your app route as shown above. The xcmetricsPlugin export is not required for basic routing.
Changelog
This changelog is produced from commits made to the XCMetrics 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.
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.