Skip to main content
Glama


Install

npm install metricui

That's it. All chart dependencies are included.


Why MetricUI?

You're building a dashboard. You need KPI cards, charts, tables. You reach for Recharts + shadcn + custom CSS and spend days wiring up formatting, dark mode, loading states, and responsive layouts.

MetricUI does all of that in one import.

import {
  MetricProvider, FilterProvider, DashboardHeader, PeriodSelector,
  MetricGrid, KpiCard, AreaChart, DonutChart, DataTable, Callout,
} from "metricui";
import "metricui/styles.css";

export default function Dashboard() {
  return (
    <MetricProvider theme="emerald">
      <FilterProvider defaultPreset="30d">
        <DashboardHeader title="Revenue" lastUpdated={new Date()} actions={<PeriodSelector comparison />} />

        <MetricGrid>
          <MetricGrid.Section title="Key Metrics" />
          <KpiCard title="Revenue" value={127450} format="currency"
            comparison={{ value: 113500 }} comparisonLabel="vs last month"
            sparkline={{ data: [89, 94, 99, 103, 109, 114, 127], previousPeriod: [78, 82, 85, 88, 91, 95, 98] }}
            conditions={[
              { when: "above", value: 120000, color: "emerald" },
              { when: "below", value: 90000, color: "red" },
            ]}
          />
          <KpiCard title="Users" value={8420} format="compact"
            comparison={[{ value: 7680, label: "vs last month" }, { value: 6200, label: "vs last year" }]}
            highlight
          />
          <KpiCard title="Churn" value={3.2} format="percent"
            comparison={{ value: 3.7, invertTrend: true }}
            goal={{ value: 2.5, showTarget: true, showRemaining: true }}
          />

          <Callout value={12.3} rules={[
            { min: 10, variant: "success", title: "Strong Growth", message: "Revenue grew {value}% this month." },
            { max: 0, variant: "error", title: "Revenue Declined", message: "Revenue dropped {value}%." },
          ]} />

          <MetricGrid.Section title="Trends" border />
          <AreaChart data={revenueData} comparisonData={prevPeriod} format="currency" title="Revenue Trend"
            referenceLines={[{ axis: "y", value: 50000, label: "Target", style: "dashed" }]}
            thresholds={[{ from: 0, to: 30000, color: "#EF4444", opacity: 0.05 }]}
          />
          <DonutChart data={planBreakdown} format="currency" title="By Plan" centerValue="$127K" centerLabel="Total" />

          <MetricGrid.Section title="Details" border />
          <DataTable data={customers} title="Top Customers" columns={columns} searchable pageSize={10} />
        </MetricGrid>
      </FilterProvider>
    </MetricProvider>
  );
}

Zero layout code. MetricGrid auto-detects component types — KPIs row up, charts pair, tables go full width. DashboardHeader shows live status with auto-ticking "Updated Xm ago". FilterProvider + PeriodSelector wire time filtering across the page. Responsive out of the box.


Features

AI Insights — Bring Your Own LLM

Drop <DashboardInsight /> into any dashboard. A floating chat button appears — click it, ask questions about your data. The AI auto-collects live data from every component, builds context-rich prompts, and streams analysis. Use @ to reference specific charts. Works with any LLM (OpenAI, Anthropic, local models). Docs →

<Dashboard ai={{ analyze: myLLM, company: "Acme Corp — B2B SaaS", context: "Q4 target: $500K" }}>
  <KpiCard title="Revenue" value={142800} aiContext="Primary metric. Enterprise drives 52%." />
  <DashboardInsight />
</Dashboard>

KPI Cards — Not Just Numbers

Sparkline with previous-period overlay. Goal progress bars. Conditional red/amber/green coloring. Multiple comparison badges. Copyable values. Drill-down links. Docs →

Charts with Reference Lines & Threshold Bands

Mark targets, benchmarks, and danger zones directly on charts. Comparison overlays show period-over-period trends as dashed lines. Works on AreaChart, LineChart, and BarChart.

<AreaChart
  data={revenueData}
  comparisonData={previousPeriod}
  referenceLines={[{ axis: "y", value: 50000, label: "Target", style: "dashed" }]}
  thresholds={[{ from: 0, to: 30000, color: "#EF4444", opacity: 0.05 }]}
  format="currency"
/>

Data-Driven Alerts

Pass a value and rules — Callout auto-selects the right variant, title, and message. Supports embedded formatted metrics, action buttons, collapsible detail, and auto-dismiss.

Expandable Data Tables

Click a row and a mini-dashboard slides open — sparklines, gauges, status indicators, badges. Plus search, multi-sort, pagination, pinned columns, 12 column types, and row conditions. Docs →

Conversion Funnels

Auto-computed stage-to-stage conversion rates. Vertical or horizontal. Smooth or linear interpolation. Docs →

Light & Dark Mode

Wikipedia live demo in light mode.

CSS variables. Zero config. Every component adapts automatically. Theming guide →

Smart Format Engine

One prop formats any value. Currency, percentages, durations, compact notation — with locale support. Docs →

<KpiCard value={127450} format="currency" />        // → $127.5K
<KpiCard value={4.2} format="percent" />             // → 4.2%
<KpiCard value={3725} format="duration" />           // → 1h 2m 5s
<KpiCard value={2400000} format="number" />          // → 2.4M

Theme Presets

One prop. Entire dashboard changes color. 8 built-in presets. Custom presets via ThemePreset type. Theming guide →

<MetricProvider theme="emerald">   // Green accent + green-first chart palette
<MetricProvider theme="rose">      // Pink accent + pink-first chart palette
<MetricProvider theme="amber">     // Warm amber everything

MetricGrid — Zero Layout Code

Drop components in. It figures out the layout. Docs →

<MetricGrid>
  <MetricGrid.Section title="Overview" />
  <KpiCard ... />  <KpiCard ... />  <KpiCard ... />
  <AreaChart ... />          {/* Auto 2/3 width */}
  <DonutChart ... />         {/* Auto 1/3 width */}
  <DataTable ... />          {/* Auto full width */}
</MetricGrid>

Filter System

Complete filter context — wire PeriodSelector, DropdownFilter, SegmentToggle, and FilterTags together with zero boilerplate. Filtering guide →

<FilterProvider defaultPreset="30d">
  <DashboardHeader title="Dashboard" actions={<PeriodSelector comparison />} />
  <SegmentToggle options={["All", "Enterprise", "SMB"]} field="segment" />
  <DropdownFilter label="Region" options={regions} field="region" multiple />
  <FilterTags />  {/* Auto-renders active filters as dismissible chips */}
</FilterProvider>

Data States

Every component handles loading, empty, error, and stale states out of the box. Docs →

Error Boundaries

One chart crashes? The rest keep running. Dev mode shows component name + actionable hints. Prod mode shows clean retry UI.

Accessibility

prefers-reduced-motion, focus-visible rings, ARIA attributes on charts, keyboard-accessible drill-downs. Docs →


Components

Cards & Metrics

Component

What it does

Docs

KpiCard

Comparison badges, sparkline overlays, goal progress, conditional coloring, copyable, drill-down

Docs

StatGroup

Multiple metrics in a dense responsive grid row with per-stat comparisons

Docs

Charts

Component

What it does

Docs

AreaChart

Gradient fills, stacking, dual Y-axis, comparison overlays, reference lines, threshold bands

Docs

LineChart

Clean lines — same props as AreaChart without fill

Docs

BarChart

6 presets, comparison/target bars, sorting, negative values, reference lines

Docs

BarLineChart

Dual-axis combo: bars + lines — unified data format

Docs

DonutChart

Center KPI content, arc labels, percentage mode

Docs

Gauge

Arc gauge with threshold zones, target markers, comparison badges

Docs

HeatMap

2D matrix, cross-hair hover, sequential + diverging color scales

Docs

Funnel

Conversion pipeline with auto-computed rates

Docs

Waterfall

Sequential +/- changes with auto running totals, connectors

Docs

BulletChart

Actual vs target with qualitative range bands

Docs

Sparkline

Inline micro-chart with reference lines, bands, trend coloring

Docs

Data

Component

What it does

Docs

DataTable

Sort, search, pagination, expandable rows, 12 column types, pinned columns, row conditions

Docs

Layout

Component

What it does

Docs

DashboardHeader

Live/stale status, auto-ticking "Updated Xm ago", breadcrumbs, action slots

Docs

MetricGrid

Smart auto-layout grid with staggered reveal animations

Docs

SectionHeader

Labeled divider with description popover, badge, action slot

Docs

Divider

Horizontal/vertical separator with label, icon, accent

Docs

Filters

Component

What it does

Docs

FilterProvider

Context that wires all filter components. useMetricFilters() hook

Guide

PeriodSelector

Date range presets, custom ranges, comparison toggle

Docs

DropdownFilter

Multi-select dimension filter with search, grouped options

Docs

SegmentToggle

Pill toggle with icons, badges, multi-select

Docs

FilterTags

Auto-renders active filters as dismissible chips

Docs

Status & Alerts

Component

What it does

Docs

Callout

Data-driven alerts with rules, {value} templates, embedded metrics

Docs

StatusIndicator

Rule-based health with 5 sizes, pulse animation, trend arrows

Docs

Badge

6 variants, 3 sizes, custom colors, icons, dismiss

Docs


AI-First: MCP Server + llms.txt

Most component libraries give you docs and hope the AI figures it out. MetricUI gives the AI structured knowledge of every component, every prop, and every pattern — so it generates production-quality dashboards on the first try.

# One command. That's it.
claude mcp add --transport stdio metricui -- npx -y @metricui/mcp-server

The difference is real

Here's what happens when you prompt an AI with "Build me a SaaS dashboard with MRR, churn, users, and revenue breakdown":

// The AI guesses at library APIs, builds everything from scratch
import { LineChart, Line, XAxis, YAxis, PieChart, Pie } from "recharts";

export default function Dashboard() {
  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold mb-6">SaaS Dashboard</h1>

      <div className="grid grid-cols-4 gap-4 mb-8">
        <div className="border rounded-lg p-4">
          <p className="text-sm text-gray-500">MRR</p>
          <p className="text-2xl font-bold">${(127450).toLocaleString()}</p>
          <p className="text-sm text-green-600">+12.3%</p>
        </div>
        <div className="border rounded-lg p-4">
          <p className="text-sm text-gray-500">Churn Rate</p>
          <p className="text-2xl font-bold">3.2%</p>
          <p className="text-sm text-green-600">-13.5%</p>
        </div>
        {/* ...more hand-built cards with no formatting engine, no sparklines,
            no conditional coloring, no goal tracking... */}
      </div>

      <LineChart width={800} height={300} data={data}>
        <XAxis dataKey="month" />
        <YAxis />
        <Line dataKey="revenue" stroke="#8884d8" />
        {/* No reference lines. No threshold bands. No comparison overlay.
            No dark mode. No loading states. No error boundaries. */}
      </LineChart>
    </div>
  );
}

Raw div cards. Manual number formatting. No sparklines, no conditions, no goals, no filters, no dark mode, no data states, no error boundaries. Every dashboard looks the same.

import {
  MetricProvider, FilterProvider, DashboardHeader, PeriodSelector,
  MetricGrid, KpiCard, Callout, AreaChart, DonutChart, BarChart,
  DataTable, Badge,
} from "metricui";
import "metricui/styles.css";

export default function Dashboard() {
  return (
    <MetricProvider theme="emerald">
      <FilterProvider defaultPreset="30d">
        <DashboardHeader
          title="SaaS Metrics"
          subtitle="Real-time metrics overview"
          lastUpdated={new Date()}
          actions={<PeriodSelector comparison />}
        />
        <MetricGrid>
          <MetricGrid.Section title="Key Metrics" />

          <KpiCard title="Monthly Revenue" value={127450} format="currency"
            comparison={{ value: 113500 }} comparisonLabel="vs last month"
            sparkline={{ data: [89, 94, 99, 103, 109, 114, 127],
              previousPeriod: [78, 82, 85, 88, 91, 95, 98], interactive: true }}
            conditions={[
              { when: "above", value: 115000, color: "emerald" },
              { when: "below", value: 90000, color: "red" },
            ]} />

          <KpiCard title="Churn Rate" value={3.2} format="percent"
            comparison={{ value: 3.7, invertTrend: true }}
            goal={{ value: 2.5, showTarget: true, showRemaining: true }}
            conditions={[
              { when: "below", value: 2.5, color: "emerald" },
              { when: "above", value: 4, color: "red" },
            ]} />

          <KpiCard title="Active Users" value={8420} format="number"
            comparison={{ value: 7680 }} copyable
            drillDown={{ label: "View breakdown", onClick: () => {} }} />

          <KpiCard title="Conversion" value={4.8} format="percent"
            comparison={{ value: 4.2 }}
            sparkline={{ data: [3.1, 3.4, 3.8, 4.0, 4.1, 4.2, 4.8] }} />

          <Callout value={12.3} rules={[
            { min: 15, variant: "success", title: "Exceptional Growth",
              message: "Revenue grew {value}% — exceeding target by 50%." },
            { min: 5, max: 15, variant: "info", title: "Healthy Growth",
              message: "Revenue grew {value}% month-over-month." },
            { max: 0, variant: "error", title: "Revenue Declined",
              message: "Revenue dropped {value}%." },
          ]} action={{ label: "View growth report", onClick: () => {} }} />

          <MetricGrid.Section title="Trends" subtitle="Last 30 days" border />

          <AreaChart data={revenueData} comparisonData={comparisonData}
            format="currency" title="Revenue Trend"
            referenceLines={[{ axis: "y", value: 50000, label: "Target",
              color: "#10B981", style: "dashed" }]}
            thresholds={[{ from: 0, to: 40000, color: "#EF4444", opacity: 0.05 }]}
            xAxisLabel="Month" yAxisLabel="Revenue ($)"
            height={360} legend />

          <DonutChart data={breakdownData} format="currency"
            title="Revenue by Plan" centerValue="$99.4K" centerLabel="Total MRR" />

          <MetricGrid.Item span="full">
            <BarChart preset="grouped" data={channelData}
              keys={["revenue", "conversions"]} indexBy="channel"
              sort="desc" format="currency" title="Channel Performance" legend />
          </MetricGrid.Item>

          <MetricGrid.Section title="Details" border />
          <DataTable data={tableData} title="Top Customers" searchable
            columns={[
              { key: "name", header: "Customer", sortable: true },
              { key: "plan", header: "Plan",
                render: (v) => <Badge variant={v === "Enterprise" ? "info" : "default"}>{String(v)}</Badge> },
              { key: "mrr", header: "MRR", format: "currency", sortable: true },
              { key: "status", header: "Status",
                render: (v) => <Badge variant={v === "active" ? "success" : v === "at-risk" ? "warning" : "danger"}>{String(v)}</Badge> },
            ]} />
        </MetricGrid>
      </FilterProvider>
    </MetricProvider>
  );
}

Same prompt. The AI with MetricUI MCP generates:

  • DashboardHeader with live status + auto-ticking "Updated Xm ago"

  • FilterProvider + PeriodSelector with comparison toggle

  • MetricGrid auto-layout (zero CSS)

  • KpiCards with conditional coloring, goal progress bars, sparkline overlays, drill-down links

  • AreaChart with dashed target reference line, danger zone threshold band, and previous-period comparison overlay

  • Data-driven Callout that auto-picks severity from a growth number

  • Sorted grouped BarChart, DonutChart with center KPI

  • Searchable DataTable with Badge status columns

  • Theme preset, dark mode, animations, error boundaries — all automatic

The AI doesn't guess. It knows. 13 tools, 26 components, every prop, every pattern. Full MCP Server docs →

llms.txt

Machine-readable documentation for AI models at /llms.txt. Every component, every prop, every type, every pattern — so even AI tools without MCP support can generate correct MetricUI code.


Roadmap

MetricUI is building toward 1.0 — cross-filtering, zero-config charts, anomaly detection, data stories, and a stable API you can build on with confidence. See what's shipped, what's next, and where we're headed:

View the full roadmap →


Built With

  • Nivo — chart rendering (line, bar, pie, heatmap)

  • Tailwind CSS — styling (ships pre-built, Tailwind not required in your project)

  • Lucide — icons

  • React 18/19


License

MIT


-
security - not tested
A
license - permissive license
-
quality - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mpmcgowen/metricui'

If you have feedback or need assistance with the MCP directory API, please join our Discord server