Chart component composition pattern
Charts are designed with composition in mind. You build charts using Recharts components (Bar, BarChart, CartesianGrid, XAxis, etc.) and only bring in custom components like ChartTooltip and ChartTooltipContent when needed.
ChartTooltip and ChartTooltipContent components
Import ChartTooltip and ChartTooltipContent from @/components/ui/chart. Use them together to add tooltips to charts: <ChartTooltip content={<ChartTooltipContent />} />. Colors are automatically referenced from the chart config.
ChartLegend and ChartLegendContent components
Import ChartLegend and ChartLegendContent from @/components/ui/chart. Use them together to add legends to charts: <ChartLegend content={<ChartLegendContent />} />. Colors are automatically referenced from the chart config.
Chart color referencing in data objects
Chart data objects can include a fill property that references chart colors: { browser: "chrome", visitors: 275, fill: "var(--color-chrome)" }
ChartContainer requires min-h class
It is required to set a min-h-[VALUE] class on the ChartContainer component for the chart to be responsive.
Chart config is decoupled from chart data
The chart config is intentionally decoupled from chart data. This allows you to share config and color tokens between charts and work independently for cases where data or color tokens live remotely or in different formats.
ChartContainer component usage
The ChartContainer component wraps your chart and requires a min-h-[VALUE] class for responsive charts. It accepts a config prop (ChartConfig type) and className prop. Example: <ChartContainer config={chartConfig} className="min-h-[200px] w-full">
Custom legend with nameKey example
Here is an example of using a custom key for legend names:
const chartData = [
{ browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
const chartConfig = {
chrome: {
label: "Chrome",
color: "var(--chart-1)",
},
safari: {
label: "Safari",
color: "var(--chart-2)",
},
} satisfies ChartConfig
<ChartLegend content={<ChartLegendContent nameKey="browser" />} />
Chart config structure
The chart config is an object where keys map to data keys. Each config entry has: label (string, human-readable name), icon (optional, Lucide React component), color (string in any format: hex, hsl, oklch, or CSS variable like var(--color-name)), and optionally a theme object with light and dark keys for theme-specific colors. The config is intentionally decoupled from chart data to allow sharing between charts.
Chart component ChartContainer minimum height requirement
The ChartContainer component requires a min-h-[VALUE] Tailwind class, a height property, or an aspect-* property to be responsive. This is necessary for ResponsiveContainer to measure on first render.
Basic chart component example
Here is a basic chart component example using ChartContainer and ChartTooltipContent:
import { Bar, BarChart } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
export function MyChart() {
return (
<ChartContainer>
<BarChart data={data}>
<Bar dataKey="value" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
)
}
Complete bar chart with grid, axis, tooltip and legend example
Here is a complete bar chart example with grid, axis, tooltip and legend:
<ChartContainer config={chartConfig} className="h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) => value.slice(0, 3)}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
Chart config example with colors
Here is a chart config example:
import { type ChartConfig } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
Chart config with CSS variables example
Here is a chart config example using CSS variables:
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig
Chart config with theme object example
Here is a chart config example with theme object for light and dark modes:
import { Monitor } from "lucide-react"
import { type ChartConfig } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
icon: Monitor,
theme: {
light: "#2563eb",
dark: "#dc2626",
},
},
} satisfies ChartConfig
Custom tooltip with labelKey and nameKey example
Here is an example of using custom keys for tooltip label and names:
const chartData = [
{ browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
const chartConfig = {
visitors: {
label: "Total Visitors",
},
chrome: {
label: "Chrome",
color: "var(--chart-1)",
},
safari: {
label: "Safari",
color: "var(--chart-2)",
},
} satisfies ChartConfig
<ChartTooltip
content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />}
/>
ChartTooltip import and basic usage
To add a tooltip to your chart, import: import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"; then add <ChartTooltip content={<ChartTooltipContent />} /> to your chart.
ChartContainer requires minimum height
The ChartContainer component must have a min-h-[VALUE] or height or aspect-ratio property set. This is required for the chart to be responsive and for ResponsiveContainer to measure on first render.
Basic chart example with Bar, BarChart, and ChartContainer
Example showing how to build a chart: import { Bar, BarChart } from "recharts"; import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"; export function MyChart() { return ( <ChartContainer> <BarChart data={data}> <Bar dataKey="value" /> <ChartTooltip content={<ChartTooltipContent />} /> </BarChart> </ChartContainer> ) }
Recharts v3 upgrade - CSS variable syntax
When upgrading to Recharts v3, use var(--chart-1) instead of hsl(var(--chart-1)) when referencing chart tokens from CSS variables.
Recharts v3 upgrade - ChartTooltip defaultIndex
When upgrading to Recharts v3, use ChartTooltip.defaultIndex for initial tooltip state only. Keep persistent active shapes in your own chart state.
Recharts v3 upgrade - Bar layout property
When upgrading to Recharts v3, remove layout from <Bar> when the parent <BarChart> already defines it.
ChartTooltip with custom labelKey and nameKey
Example of using custom keys with ChartTooltip: <ChartTooltip content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />} />. This will use the value from the chartConfig key 'visitors' for the label and values from the data key 'browser' for the tooltip names.
ChartLegend and ChartLegendContent usage
To add a legend to your chart, import and use: import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"; then add <ChartLegend content={<ChartLegendContent />} /> to your chart.
ChartLegendContent with custom nameKey
Example of using custom nameKey with ChartLegendContent: <ChartLegend content={<ChartLegendContent nameKey="browser" />} />. This will use values from the data key 'browser' for the legend names instead of the default data key.
Reference chart colors in components using var(--color-KEY)
To use theme colors from the chart config in components, reference them using var(--color-KEY) format. For example: <Bar dataKey="desktop" fill="var(--color-desktop)" />
Reference chart colors in chart data
Example of using chart colors in chart data: const chartData = [ { browser: "chrome", visitors: 275, fill: "var(--color-chrome)" }, { browser: "safari", visitors: 200, fill: "var(--color-safari)" } ]
Reference chart colors in Tailwind
To use chart colors in Tailwind CSS, use the format: <LabelList className="fill-(--color-desktop)" />
Chart accessibility layer
You can enable the accessibilityLayer prop on chart components like LineChart to add an accessible layer that provides keyboard access and screen reader support to your charts. Example: <LineChart accessibilityLayer />
Chart data shape flexibility
Your chart data can be in any shape. You are not limited to a specific data structure. Use the dataKey prop to map your data to the chart.
Add CartesianGrid to chart
To add a grid to your chart, import CartesianGrid from recharts and add it to your chart: import { CartesianGrid } from "recharts"; then add <CartesianGrid vertical={false} /> to your BarChart or other chart component.
Add XAxis to chart
To add an x-axis to your chart, import XAxis from recharts and configure it: import { XAxis } from "recharts"; then add <XAxis dataKey="month" tickLine={false} tickMargin={10} axisLine={false} tickFormatter={(value) => value.slice(0, 3)} /> to your chart.