Skip to content
microcharts

microcharts vs Recharts — inline charts comparison

A narrow, factual comparison for one decision — a chart inside a sentence, table cell, or KPI in React. Measured bundle sizes, dependency counts, RSC behavior, and accessibility defaults. Recharts stays the right call for full dashboard surfaces.

Recharts is a full chart library and microcharts is not a replacement for it. If your page is the chart — axes, legend, tooltip, brush — stop reading and use Recharts. This page compares the two for exactly one job: a word-sized chart inside an interface, where the surface is mostly words and UI.

The broader positioning lives in When to use microcharts and Full chart libraries. This page is the measured detail for the Recharts decision.

The numbers

SignalRecharts 3.9.2microcharts Sparkline
Gzip for one chart~106 kB (tree-shaken LineChart)3.99 kB static · 6.64 kB interactive
Whole package (gzip)~145 kBone subpath; catalog median 2.6 kB static
Runtime dependencies110 (React is a peer)
Typical jobFull chart surfaces (axes, legends, tooltips)Word-sized marks inside UI / prose / RSC

Orientation only — different jobs. Recharts package via bundlephobia 2026-07; one-chart via esbuild tree-shake 2026-07. microcharts from .size-limit.json (CI).

Both microcharts columns come from .size-limit.json, the CI gate that fails the build when a chart grows past its budget. The Recharts numbers are pinned with version, method, and date — they are orientation, not a scoreboard, and they will age.

Where the difference actually shows

Bundle cost per mark. A tree-shaken Recharts LineChart carries the shared Recharts core. That cost is fine amortized over a dashboard; it is hard to justify for one sparkline in a table header. microcharts imports one chart per subpath, so a page that uses only Sparkline pays only for Sparkline.

Server Components. Recharts components are hook-based, so in an App Router app they run inside a client boundary and ship their JavaScript. The microcharts default export is hook-free static SVG — it renders in an RSC with zero client JavaScript, and interactivity is a separate opt-in /interactive import.

Accessibility defaults. Recharts ships an accessibility layer, on by default in v3 — keyboard navigation and ARIA roles on the chart surface. A natural-language description of the data is still yours to write. Every microchart is role="img" with that description generated from the data by default (describeSeries); the decorative opt-out is explicit (summary={false}).

Chart chrome. Recharts draws axes, ticks, legends, and tooltips because dashboard surfaces need them. microcharts hard-codes them away because word-sized marks cannot afford them. Neither choice is a defect; they serve different surfaces.

Reach for Recharts

  • The page is mostly chart: analytics views, report panels, explorable dashboards
  • You need ticks, legends, brush, zoom, or a tooltip that follows the pointer
  • Your team already has a Recharts component tree it trusts

Reach for microcharts

  • The mark sits in a sentence, a table cell, a tab, a KPI card, or a streamed AI reply
  • You want static chart SVG out of a React Server Component with nothing to hydrate
  • You want an accessible name generated from the data without wiring it per chart
  • Budget matters per mark: ~2–7 kB interactive · ~1–4 kB static gzip, zero runtime dependencies

Same app, both libraries

This is the common ending, not a compromise:

// analytics page — Recharts
<ResponsiveContainer width="100%" height={240}>
  <LineChart data={rows}>…</LineChart>
</ResponsiveContainer>;

// the table that links to it — microcharts
import { Sparkline } from "@microcharts/react/sparkline";
<Sparkline data={row.series} width={72} height={16} dots="none" summary={false} />;

What this page is not saying

  • Not "Recharts is heavy" — it is correctly sized for the job it does
  • Not "microcharts can replace your dashboards" — it cannot and does not try
  • The gzip figures are dated pins, not live measurements

Next