@tanstack/react-charts is a thin lifecycle and SSR adapter around @tanstack/charts. Chart definitions, scale resolution, guide layout, scenes, rendering, animation, and interaction remain in the framework-neutral core.
export { Chart } from '@tanstack/react-charts'
export type {
ChartCommonProps,
ChartProps,
ChartDefinition,
ChartPoint,
ChartTooltipBodyRenderContext,
} from '@tanstack/react-charts'Choose Canvas or an application-supplied renderer through an explicit subpath:
import { Chart as CanvasChart } from '@tanstack/react-charts/canvas'
import { Chart as RendererChart } from '@tanstack/react-charts/core'CanvasChart selects the optional built-in renderer. RendererChart requires a renderer prop. The default Chart remains SVG-based, so importing the default adapter does not pull Canvas into its module graph.
Use the re-exported definition and point types only when an application API needs an explicit annotation. Ordinary component use is inferred.
The adapter creates one ChartRuntime per mounted component and asks the selected renderer for its initial markup during React render. After commit:
The chart surface is memoized after its first render. Scene changes are painted by the shared host rather than by rebuilding the surface through React. Memoize definitions that capture component values with useMemo; module-scope definitions need no component memoization.
React batching may omit intermediate application states. Every committed prop set forwarded to the host remains declarative and complete.
The default SVG entry emits:
The client renders the same initial structure, then the layout effect adopts and reconciles that SVG. There is no placeholder-only server mode.
The Canvas entry emits the same outer structure with a named Canvas root and two aria-hidden canvases. It does not paint pixels on the server. The client adopts those elements, paints after mount, and attaches the same focus, keyboard, tooltip, and selection host.
Use deterministic data, scale domains, definitions, dimensions, and custom renderers on server and client. The adapter generates a sanitized idPrefix from React.useId() when one is not supplied, keeping document resources stable through hydration.
tabIndex defaults to 0 on both server and client. keyboard: false forces it to -1.
For resource-aware gradients or clipping, pass the same renderer on both server and client. See Rendering and export.
The adapter renders two nested containers:
.ts-chart-host
.ts-chart-surface
svg.ts-chart | div.ts-chart-canvasThe outer host has position: relative.
| Props | Outer host behavior | Scene behavior |
|---|---|---|
| no width, fixed height | width: 100%; fixed height | container width × fixed height |
| fixed width and height | fixed CSS width and height | same fixed scene dimensions |
| fixed width and aspectRatio | fixed width and CSS ratio | fixed width divided by ratio |
| positive aspectRatio, no height | width: 100%; CSS aspect ratio | measured width divided by ratio |
| neither height nor aspectRatio | width: 100%; height: 320px | measured width × 320 |
initialWidth defaults to 640 and controls the initial/server scene when width is absent. A fixed height takes precedence over aspectRatio. Nonpositive and nonfinite ratios fall back to the default height.
The DOM host observes responsive width and measures the inherited container font. Its exact fallback and relayout behavior is documented in DOM host.
React-specific presentation props apply to the outer .ts-chart-host:
<Chart
definition={definition}
ariaLabel="Revenue"
className="dashboard-chart"
style={{ minHeight: 240, color: 'var(--foreground)' }}
/>Do not give style.width a value that conflicts with a fixed width prop. The style controls the outer CSS box, while the prop continues to lock the scene width.
Core renderer className options apply to a surface when calling it directly. The React adapter's className intentionally owns the outer element instead.
renderTooltipBody mounts React content into the native tooltip surface. Its context provides points, content, defaultBody, pinned, and dismiss. Composing defaultBody keeps the core title, rows, formatting, and swatches; arbitrary React content can sit beside it.
The shared host owns a stable body mount target and releases it when the tooltip is hidden, custom rendering is disabled, or the chart is destroyed. React owns the rendered component lifecycle. A custom body is inert while transient, so display-only content can remain visible but controls should render only while pinned is true. Definition tooltip.portal: true promotes the whole surface above clipped ancestors without changing this React API.
Define a fixed chart outside component render:
import { defineChart } from '@tanstack/charts'
const definition = defineChart({
marks: [],
x: null,
y: null,
})For live state, memoize the complete definition against the values it captures. Definition identity is the application update boundary; see Chart Definition API.
Every committed prop set is forwarded to the host. Focus, grouped focus, selection, and render callbacks therefore use the latest committed functions. Callback types are inferred from the definition's marks.
The adapter does not redefine:
Use Scales and D3 for the injected primitive boundary and the core reference for those APIs.