44 components. 18 chart types. AI-powered analysis. Cross-filtering. Drill-downs. Export. Stop assembling dashboards from parts — and let your dashboard explain itself.
npm install metricuiMIT · Open Source · FreeLive Components
Real MetricUI components rendering below. Sparklines, comparisons, goals, conditional colors — no screenshots.
Superpowers
Drop in one component. Connect your LLM. End users ask questions about their data — the AI sees every chart, every filter, every number. @ mention specific metrics. Get answers grounded in what's actually on screen.
Click a donut slice, a bar, a table row — every other component on the page filters to match. One prop: crossFilter. No wiring code. Click again to clear. Signal-only architecture — you own the data, we own the interaction.
drillDown={true} auto-generates a detail panel. Or pass a function for custom content. Slide-over or modal. Nested up to 4 levels with breadcrumbs. Works on every component — KPIs, charts, tables.
exportable on MetricProvider. Every component gets a download button. 4x DPI PNGs via modern-screenshot. CSV with filter metadata. Clean filenames. The finance team stops asking you for screenshots.
Before & After
One KPI card with formatting, comparison, sparkline, loading, error handling, dark mode, export, and AI context.
// The usual way — Recharts + shadcn + custom everything
import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer } from "recharts";
import { Card, CardHeader, CardTitle, CardContent } from "@/ui/card";
import { Skeleton } from "@/ui/skeleton";
import { TrendingUp, TrendingDown } from "lucide-react";
import { cn } from "@/lib/utils";
function formatCurrency(n: number) {
return new Intl.NumberFormat("en-US", {
style: "currency", currency: "USD",
minimumFractionDigits: 0, maximumFractionDigits: 0,
}).format(n);
}
function RevenueCard({ value, prev, sparkline, loading, error }) {
if (loading) return (
<Card>
<CardHeader><Skeleton className="h-4 w-24" /></CardHeader>
<CardContent className="space-y-3">
<Skeleton className="h-8 w-32" />
<Skeleton className="h-4 w-20" />
<Skeleton className="h-16 w-full" />
</CardContent>
</Card>
);
if (error) return (
<Card>
<CardContent className="py-8 text-center text-sm text-red-500">
Failed to load — <button onClick={() => window.location.reload()}>Retry</button>
</CardContent>
</Card>
);
const change = prev !== 0 ? ((value - prev) / prev) * 100 : 0;
const isPositive = change >= 0;
const Icon = isPositive ? TrendingUp : TrendingDown;
return (
<Card>
<CardHeader>
<CardTitle className="text-xs font-medium text-muted-foreground uppercase">
Revenue
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-2xl font-bold">{formatCurrency(value)}</p>
<div className={cn("flex items-center gap-1 text-sm mt-1",
isPositive ? "text-green-600" : "text-red-600"
)}>
<Icon className="h-3 w-3" />
<span>{isPositive ? "+" : ""}{change.toFixed(1)}% vs last month</span>
</div>
{sparkline && (
<div className="mt-3 h-16">
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={sparkline.map((v, i) => ({ i, v }))}>
<Area type="monotone" dataKey="v" stroke="#6366f1"
fill="url(#grad)" strokeWidth={1.5} />
</AreaChart>
</ResponsiveContainer>
</div>
)}
</CardContent>
</Card>
);
}
// 65 lines. Still missing: goal progress, conditional coloring,
// comparison badges, copy-to-clipboard, drill-down, dense mode,
// dark mode, null handling, count-up animation, export...Quick Start
Dashboard wrapper, filters, cross-filtering, drill-downs, export, and AI chat — all configured.
import { Dashboard, KpiCard, AreaChart, MetricGrid, DashboardInsight } from "metricui";
import "metricui/styles.css";
export default function MyDashboard() {
return (
<Dashboard
theme="emerald"
filters={{ defaultPreset: "30d" }}
exportable
ai={{ analyze: myLLM, company: "Acme Corp", context: "Q4 revenue dashboard" }}
>
<MetricGrid>
<KpiCard title="Revenue" value={127450} format="currency"
comparison={{ value: 113500 }}
aiContext="Our north star metric. Enterprise drives 52%." />
<KpiCard title="Users" value={8420} format="number"
goal={{ value: 10000, showProgress: true }} />
<AreaChart data={revenueData} index="month" categories={["revenue"]}
title="Revenue Over Time" crossFilter drillDown />
</MetricGrid>
<DashboardInsight />
</Dashboard>
);
}Everything Included
KPI cards, 18 chart types, tables, layout, formatting, theming — one package. No glue code.
Loading skeletons, empty states, error retry, stale indicators. On every component. Pass a prop.
FilterBar + PeriodSelector + DropdownFilter + SegmentToggle + FilterTags. All wired through context.
One prop changes everything. Indigo, emerald, rose, amber, cyan, violet, slate, orange. CSS variables.
Auto column inference on tables. Auto-format from key names. MetricGrid auto-layout. It just works.
Claude, Cursor, Copilot generate correct MetricUI code on the first try. Full API surface exposed.
Every component tested. Every prop typed. BaseComponentProps inherited everywhere. Ship with confidence.
MIT license. No pro tier. No gates. KPIs, charts, tables, filters, layout, AI — everything ships.
Live Demos
Five fully interactive dashboards. Real data. Real AI. Real cross-filtering. Click around.
GA-style · tab nav · AI insights · cross-filter · per-device data
ExploreMRR · churn · funnel · industry breakdown · AI analysis
ExploreReal facebook/react data · commit velocity · issue triage
ExploreReal-time streaming · bot/human analysis · edit velocity
ExplorePopulation · GDP · languages · 4-level drill-downs
ExploreCompare
Honest, detailed comparisons against the libraries you already know. We call out the good in every tool — then show where MetricUI goes further.
The most popular React charting library. Great charts — but you still need everything else.
Read comparisonBeautiful Tailwind components, now part of Vercel. See how the two dashboard libraries compare.
Read comparisonOwn-the-code philosophy meets ship-the-dashboard. The lines-of-code difference is striking.
Read comparisonThe OG charting library. Canvas rendering meets SVG — and the trade-offs matter more than you think.
Read comparisonBest-in-class for infrastructure monitoring. But if you're building product dashboards, read this.
Read comparisonStop assembling six libraries into a dashboard. Start building one that thinks.