Developer documentation

Beautiful in your app.

Local TypeScript, familiar chart engines, and your existing shadcn theme. No hosted chart service or runtime subscription dependency.

Installation

Start with a React application using Tailwind CSS and an initialized shadcn setup. Next.js and Vite + React are supported workflows. If shadcn is already initialized, skip the first command.

npx shadcn@latest init
npx shadcn@latest add https://beautifulcharts.dev/r/signal-ribbon.json

The full URL works without configuring a registry namespace. The CLI installs the selected component, its recursive shared dependencies, and only the chart engine it uses. It does not add account SDKs, analytics, billing code, or agent instruction files.

"use client";

import { SignalRibbon, type SignalRibbonDatum } from "@/components/beautiful-charts/signal-ribbon";

const data: SignalRibbonDatum[] = [
  { label: "Jan", value: 24 },
  { label: "Feb", value: 38 },
  { label: "Mar", value: 31 },
];

export function Revenue() {
  return <SignalRibbon data={data} title="Revenue"
    subtitle="Monthly performance"
    valueFormatter={(value) => `$${value.toLocaleString()}`} />;
}

Manual installation

Open any free chart and choose Source. Install its listed npm dependencies and copy every displayed file, including helpers and the MIT license file, into the listed paths. Keep the import alias aligned with your app. Every chart’s API table and type definitions are derived from those exact source files.

Framework boundaries

Charts are client components. Import them into a client boundary when passing callbacks or formatters in Next.js. ECharts initializes in an effect and disposes its instance on unmount; it does not access the browser during server rendering. Neither chart engine requires Next.js in the downloaded source.

If Tailwind classes are missing, confirm the component directory is included in your app’s Tailwind source detection. If the CLI cannot find your alias, finish shadcn initialization first. If an install prompts to overwrite a shared file, review your local edits before accepting.

Theming & colors

Cards inherit --card, --card-foreground, --border, --muted, --muted-foreground, and --destructive. Series use --chart-1 through --chart-5. The surrounding app controls the font. No global stylesheet or brand theme is installed by our registry.

Your existing shadcn light/dark theme remains authoritative. Recharts uses CSS colors directly; the ECharts surface resolves scoped CSS variables and modern color values for Canvas or SVG and refreshes when ancestor theme classes or inline styles change. If you change colors only through an external stylesheet at runtime, remount the chart or also update an ancestor theme class.

.analytics {
  --chart-1: #2563eb;
  --chart-2: #7c3aed;
  --chart-3: #c2410c;
  --chart-4: #047857;
  --chart-5: #be185d;
}

/* Optional original brand palette, not required by the components. */
.analytics-brand {
  --card: #101310;
  --card-foreground: #f3f4ed;
  --border: #292d29;
  --muted: #222822;
  --muted-foreground: #92988f;
  --destructive: #ff775e;
  --chart-1: #d7ff45;
  --chart-2: #8792ff;
  --chart-3: #ff775e;
  --chart-4: #55e6a5;
  --chart-5: #b57cff;
}

Series configuration

Foundations accept a typed series array with keys, labels, and colors. Use semantic CSS variables to follow themes, or explicit colors when a series has fixed business meaning. Stacking uses stackId for Recharts and stack for ECharts. Recipe composition is intentionally specific; change its local source when a recipe does not expose a series prop.

<RechartsAreaFoundation
  data={[{ month: "Jan", actual: 32, forecast: 38 }, { month: "Feb", actual: 48, forecast: 45 }]}
  xKey="month"
  series={[
    { key: "actual", label: "Actual", color: "var(--chart-1)", stackId: "total" },
    { key: "forecast", label: "Forecast", color: "var(--chart-2)", stackId: "total" },
  ]}
  fill="gradient" showLegend
/>

Customization

Free and premium components use the same developer model: editable source with no runtime paywall. Preview controls are not a separate hosted feature. The Usage tab produces typed props for the current settings, while theme and palette changes remain ordinary CSS.

Responsive size

Both engines track container width automatically. Place a chart in a grid with min-width: 0. Use className for the card’s spacing and border. The default plot is 224px tall; to change it, edit ChartFrame’s plot wrapper and keep the engine container at full width/height. Resizing the card alone does not change the plot height.

Recharts

Area, line, and bar foundations provide legends, tooltips, range brushes, selection callbacks, and typed series controls. Area offers gradient/solid/no fill; line offers curves, dots, dashed series and reference lines; bar offers orientation, stacking and corner radius. The horizontal bar foundation does not display an X-axis brush. Selection is also available through the accessible data table. Range callbacks return start/end data indexes.

Use children for native ReferenceLine, Legend, Brush, axis or label components, or edit the installed source. Add an explicit YAxis when assigning a composed series to an additional yAxisId. There is no proprietary wrapper API to learn.

<RechartsLineFoundation
  showDots showLegend showBrush
  onSelect={({ dataIndex, datum }) => { /* update your app */ }}
  onRangeChange={({ startIndex, endIndex }) => { /* filter your data */ }}
/> 

Apache ECharts

Choose renderer="canvas" or renderer="svg". Area, line, and bar foundations provide legends, tooltips, a native range slider, selection and range callbacks. Selection uses the native event payload; keyboard table selection includes type: "keyboard". Range callbacks use the native datazoom payload (percentages, with batch payloads possible). See your component’s exact types before handling an event.

optionOverrides is a shallow top-level merge. Passing series, xAxis, or tooltip replaces that entire option—not just one nested property. Import and register additional ECharts modules in the local component when using additional features. This keeps free installs small and renderer-specific.

<EChartsBarFoundation
  renderer="svg" showLegend showBrush
  onSelect={(params) => { /* validate the unknown native payload */ }}
  optionOverrides={{ tooltip: { show: false } }}
/>

Accessibility & states

Every free chart includes a description and expandable data table. Set ariaDescription to explain the business conclusion, not just the shape. Where selection is supported, table buttons offer a keyboard alternative to pointer interactions. Legends are not the sole way to obtain data.

Use isLoading for the loading state and an empty data array for the empty state. Sankey uses empty nodes and links; Correlation Matrix uses an object with empty labels and values arrays. Recipe validations report malformed or out-of-range values without pretending they are valid measurements. Caller data must conform to the exported TypeScript schema. Avoid NaN and Infinity; preserve nulls only where the schema allows missing observations.

Animations honor the browser’s reduced-motion preference. Keep color contrast appropriate for your theme; arbitrary user-selected colors can reduce contrast. Data tables remain available when color or motion is not usable.

Licensing

Free chart source is MIT licensed, including commercial use. Keep the supplied copyright and license notice with redistributions. Dependencies retain their own licenses. The platform application is private; downloading a free component does not require its source to be open.

Premium designs are a separate commercial offering. They will include editable source and a commercial license rather than being silently distributed through the public free registry. Availability and payment are not enabled merely because a preview is displayed.

Component reference