Skip to main content

Overview

@kuzenbo/charts provides a complete suite of production-ready chart components built on Recharts. It includes 13 chart types with full theming support, interactive legends, tooltips, and responsive behavior.

Installation

npm install @kuzenbo/charts @kuzenbo/core @kuzenbo/theme recharts
@kuzenbo/charts requires React 19+, recharts, @kuzenbo/core, and @kuzenbo/theme as peer dependencies.

Quick start

Create your first chart in three steps:
1

Import the chart component

import { LineChart } from "@kuzenbo/charts/ui/line-chart";
2

Define your data and series

const data = [
  { month: "Jan", revenue: 172000, target: 180000 },
  { month: "Feb", revenue: 186000, target: 190000 },
  { month: "Mar", revenue: 201000, target: 205000 },
];

const series = [
  { name: "revenue", label: "Revenue", color: "var(--color-chart-1)" },
  { name: "target", label: "Target", color: "var(--color-chart-4)" },
] as const;
3

Render the chart

export function RevenueChart() {
  return (
    <LineChart
      chartRootProps={{ className: "h-80 w-full" }}
      data={data}
      dataKey="month"
      series={series}
      valueFormatter={(value) => `$${value.toLocaleString()}`}
      withLegend
    />
  );
}

Available chart types

Kuzenbo includes 13 production-ready chart components:

Cartesian charts

Line chart

Trend visualization with support for multiple series, curves, and gradients.
import { LineChart } from "@kuzenbo/charts/ui/line-chart";

Bar chart

Comparison visualization with vertical/horizontal orientation and stacking.
import { BarChart } from "@kuzenbo/charts/ui/bar-chart";

Area chart

Filled line charts for cumulative data and range visualization.
import { AreaChart } from "@kuzenbo/charts/ui/area-chart";

Composite chart

Mix lines, bars, and areas in a single chart for complex comparisons.
import { CompositeChart } from "@kuzenbo/charts/ui/composite-chart";

Distribution charts

Scatter chart

Correlation and distribution visualization with bubble support.
import { ScatterChart } from "@kuzenbo/charts/ui/scatter-chart";

Bubble chart

Three-dimensional data with x, y, and size dimensions.
import { BubbleChart } from "@kuzenbo/charts/ui/bubble-chart";

Heatmap

Matrix visualization for correlation and intensity data.
import { Heatmap } from "@kuzenbo/charts/ui/heatmap";

Circular charts

Pie chart

Part-to-whole relationships with percentage breakdown.
import { PieChart } from "@kuzenbo/charts/ui/pie-chart";

Donut chart

Hollow pie chart with center metric support.
import { DonutChart } from "@kuzenbo/charts/ui/donut-chart";

Radial bar chart

Circular progress and comparison visualization.
import { RadialBarChart } from "@kuzenbo/charts/ui/radial-bar-chart";

Specialized charts

Radar chart

Multi-dimensional comparison across categories.
import { RadarChart } from "@kuzenbo/charts/ui/radar-chart";

Funnel chart

Conversion funnel and process flow visualization.
import { FunnelChart } from "@kuzenbo/charts/ui/funnel-chart";

Sparkline

Compact inline trend indicator without axes.
import { Sparkline } from "@kuzenbo/charts/ui/sparkline";

Chart architecture

Kuzenbo charts follow a layered architecture:

Prebuilt charts

High-level components for common use cases. Import from @kuzenbo/charts/ui/*:
import { LineChart } from "@kuzenbo/charts/ui/line-chart";
import { BarChart } from "@kuzenbo/charts/ui/bar-chart";
import { DonutChart } from "@kuzenbo/charts/ui/donut-chart";

Primitives

Low-level building blocks for custom charts:
import { Chart } from "@kuzenbo/charts";

function CustomChart() {
  return (
    <Chart.Root className="h-80">
      <Chart.Provider config={chartConfig}>
        <Chart.Style />
        <Chart.Frame>
          {/* Recharts components */}
        </Chart.Frame>
        <Chart.Legend />
      </Chart.Provider>
    </Chart.Root>
  );
}

Core primitives

Chart.Root
component
Outer container with responsive sizing and theme integration.
Chart.Provider
component
Context provider for chart configuration and color mapping.
Chart.Style
component
Injects CSS custom properties for series colors.
Chart.Frame
component
Responsive container wrapper for Recharts components.
Chart.Tooltip
component
Customizable tooltip with value formatting.
Chart.Legend
component
Interactive legend with highlight support.

Color system

Kuzenbo charts use semantic color tokens that adapt to your theme:

Chart color variables

--color-chart-1: oklch(0.65 0.25 270);
--color-chart-2: oklch(0.7 0.2 180);
--color-chart-3: oklch(0.75 0.15 120);
--color-chart-4: oklch(0.6 0.22 30);
--color-chart-5: oklch(0.68 0.18 330);

Series configuration

Define series with explicit colors:
const series = [
  { name: "revenue", label: "Revenue", color: "var(--color-chart-1)" },
  { name: "expenses", label: "Expenses", color: "var(--color-chart-2)" },
  { name: "profit", label: "Profit", color: "var(--color-chart-3)" },
];

Custom colors

Override chart colors globally or per instance:
/* Global override */
:root {
  --color-chart-1: oklch(0.65 0.3 350);
  --color-chart-2: oklch(0.7 0.25 280);
}

/* Component-specific */
.revenue-chart {
  --color-chart-1: oklch(0.6 0.22 140);
}

Configuration object

The ChartProvider accepts a configuration object for series metadata:
import type { ChartConfig } from "@kuzenbo/charts";

const chartConfig: ChartConfig = {
  revenue: {
    label: "Revenue",
    color: "var(--color-chart-1)",
  },
  expenses: {
    label: "Expenses",
    color: "var(--color-chart-2)",
  },
  profit: {
    label: "Profit",
    color: "var(--color-chart-3)",
  },
};

Using the configuration

import { Chart } from "@kuzenbo/charts";

function CustomChart() {
  return (
    <Chart.Root className="h-80">
      <Chart.Provider config={chartConfig}>
        {/* Chart content */}
      </Chart.Provider>
    </Chart.Root>
  );
}

Responsive behavior

All charts include responsive sizing:

AutoSize component

import { Chart } from "@kuzenbo/charts";

function ResponsiveChart() {
  return (
    <Chart.Root className="w-full">
      <Chart.AutoSize>
        {({ width, height }) => (
          <Chart.Frame width={width} height={height}>
            {/* Chart content */}
          </Chart.Frame>
        )}
      </Chart.AutoSize>
    </Chart.Root>
  );
}

Min height token

Control default chart height:
:root {
  --kb-chart-min-height: 280px;
}

.dashboard-chart {
  --kb-chart-min-height: 400px;
}

Hooks and utilities

Kuzenbo exposes Recharts hooks for custom chart logic:

useChartConfig

Access chart configuration:
import { Chart } from "@kuzenbo/charts";

function CustomTooltip() {
  const config = Chart.useConfig();
  const label = config.revenue?.label; // "Revenue"
  return <div>{label}</div>;
}

useSeriesColor

Resolve series colors:
import { Chart } from "@kuzenbo/charts";

function CustomLegend() {
  const revenueColor = Chart.useSeriesColor("revenue");
  return <span style={{ color: revenueColor }}>Revenue</span>;
}

useSeriesColorVar

Get CSS variable reference:
import { Chart } from "@kuzenbo/charts";

function CustomElement() {
  const colorVar = Chart.useSeriesColorVar("revenue");
  // Returns: "var(--color-chart-1)"
  return <div style={{ backgroundColor: colorVar }} />;
}

Recharts hooks

All Recharts hooks are re-exported:
import { Chart } from "@kuzenbo/charts";

function InteractiveChart() {
  const isActive = Chart.useIsTooltipActive();
  const dataPoints = Chart.useActiveTooltipDataPoints();
  const width = Chart.useChartWidth();
  const height = Chart.useChartHeight();
  
  return <div>Chart width: {width}px</div>;
}

Interactive features

Legend highlighting

Enable legend-based series highlighting:
<LineChart
  data={data}
  dataKey="month"
  series={series}
  enableLegendHighlight
  withLegend
/>
When enabled, hovering a legend item dims other series.

Custom tooltips

Override tooltip content:
import type { ChartTooltipContentProps } from "@kuzenbo/charts";

function CustomTooltip(props: ChartTooltipContentProps) {
  if (!props.active || !props.payload) return null;
  
  return (
    <div className="rounded-lg border bg-background p-2 shadow-md">
      <p className="font-semibold">{props.label}</p>
      {props.payload.map((entry) => (
        <p key={entry.name} style={{ color: entry.color }}>
          {entry.name}: {entry.value}
        </p>
      ))}
    </div>
  );
}

<LineChart
  data={data}
  dataKey="month"
  series={series}
  tooltipProps={{
    content: <CustomTooltip />,
  }}
/>

Reference lines

Add horizontal or vertical reference lines:
<LineChart
  data={data}
  dataKey="month"
  series={series}
  referenceLines={[
    {
      y: 180000,
      label: "Target",
      color: "var(--kb-destructive)",
      strokeDasharray: "3 3",
    },
  ]}
/>

Advanced examples

Multi-axis chart

const series = [
  { name: "revenue", label: "Revenue", yAxisId: "left" },
  { name: "margin", label: "Margin %", yAxisId: "right" },
];

<LineChart
  data={data}
  dataKey="month"
  series={series}
  withRightYAxis
  rightYAxisProps={{
    tickFormatter: (value) => `${value}%`,
  }}
  valueFormatter={(value) => `$${value.toLocaleString()}`}
/>

Gradient fill

<LineChart
  type="gradient"
  data={data}
  dataKey="month"
  series={[{ name: "revenue", label: "Revenue" }]}
  gradientStops={[
    { offset: 0, color: "var(--color-chart-1)", opacity: 0.8 },
    { offset: 100, color: "var(--color-chart-1)", opacity: 0 },
  ]}
/>

Stacked bar chart

import { BarChart } from "@kuzenbo/charts/ui/bar-chart";

<BarChart
  data={data}
  dataKey="month"
  series={series}
  layout="horizontal"
  stacked
  withLegend
/>

Sparkline with trend

import { Sparkline } from "@kuzenbo/charts/ui/sparkline";

<Sparkline
  data={data}
  dataKey="value"
  trendDirection="up"
  trendColors={{
    up: "var(--kb-success)",
    down: "var(--kb-destructive)",
    neutral: "var(--kb-muted-foreground)",
  }}
  withGradient
/>

Best practices

Always use var(--color-chart-*) variables instead of hardcoded colors to ensure theme compatibility:
// Good
const series = [
  { name: "revenue", color: "var(--color-chart-1)" },
];

// Avoid
const series = [
  { name: "revenue", color: "#3b82f6" },
];
Use the valueFormatter prop for consistent number formatting across tooltips and labels:
<LineChart
  valueFormatter={(value) => 
    new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
    }).format(value)
  }
/>
Always define chart height via className or style to prevent layout shifts:
<LineChart
  chartRootProps={{ className: "h-80 w-full" }}
  // ...
/>
Use connectNulls for line/area charts to handle gaps in data:
<LineChart
  connectNulls
  data={[
    { month: "Jan", value: 100 },
    { month: "Feb", value: null },
    { month: "Mar", value: 150 },
  ]}
/>

Performance considerations

All chart components are client-side only. Always use the "use client" directive when importing charts in Next.js App Router.
"use client";

import { LineChart } from "@kuzenbo/charts/ui/line-chart";

Large datasets

For datasets with 500+ points:
  1. Consider data aggregation or sampling
  2. Disable animations: chartProps={{ isAnimationActive: false }}
  3. Use virtualization for scrollable charts
  4. Implement pagination or time-based filtering

Lazy loading

Dynamically import charts to reduce initial bundle size:
import dynamic from "next/dynamic";

const LineChart = dynamic(
  () => import("@kuzenbo/charts/ui/line-chart").then((mod) => mod.LineChart),
  { ssr: false }
);

Theme runtime

Understand Kuzenbo’s theming system.

Build docs developers (and LLMs) love