Pipecat UI
Components

Metric

Single-datapoint metric tile — label, big tabular value, optional unit — fully generic and props-driven.

Open in Storybook

TTFB · tts231.8ms
TTFB · llm512.4ms
Processing · stt48.2ms
Prompt tokens12,840
Completion tokens3,956
TTFB · smart-turn

Installation

pnpm dlx shadcn@latest add @pipecat/metric

Usage

Metric is deliberately open: it renders whatever number you hand it and never reads Pipecat state itself, so it works for latency, token counts, cost, FPS — anything realtime. Formatting is steered entirely by props and memoized per value:

import { Metric } from "@/components/pipecat/metric";

<Metric label="Round trip" value={182.4} unit="ms" />
<Metric label="Total cost" value={0.0382} format={(v) => `$${v.toFixed(4)}`} />
<Metric label="TTFB · tts" value={null} unit="ms" />  {/* renders the – empty state */}

To make a tile live with Pipecat data, pair it with a value hook from usePipecatMetrics:

import { usePipecatMetricValue } from "@/hooks/use-pipecat-metrics";

function TTFBTile() {
  const ttfb = usePipecatMetricValue("ttfb", "CartesiaTTSService#0");
  return (
    <Metric
      label="TTFB · tts"
      value={ttfb === null ? null : ttfb * 1000}
      unit="ms"
    />
  );
}

The Pipecat-opinionated composition — token totals, per-processor latency tiles, time-series charts — lives in the Metrics block, which feeds this component via props.

A tile exposes data-state="live" | "empty" and data-slot="metric" / metric-label / metric-value for styling.

Key props

PropTypeDescription
labelReactNodeTile label.
valuenumber | nullDatapoint; null/undefined/non-finite renders the empty state.
unitstringUnit suffix rendered after the value.
format(value: number) => stringValue formatter (default: locale string, ≤1 decimal). Memoized per value.
emptyReactNodeRendered when there is no value (default ).

On this page