TanStack Charts builds a platform-neutral scene before the selected renderer produces output. React, Preact, Vue, Solid, Svelte, and Octane use the same runtime and renderer on the server and in the browser.
| Adapter | Server output | Browser contract |
|---|---|---|
| React | Complete SVG; Canvas shell | Hydrates and adopts the existing surface |
| Preact | Complete SVG | Hydrates before the shared host mounts |
| Vue | Complete SVG | Hydrates before the shared host mounts |
| Solid | Complete SVG | Hydrates before the shared host mounts |
| Svelte | Complete SVG | Hydrates before the shared host mounts |
| Octane | Complete SVG; Canvas shell | Hydrates and adopts the existing surface |
| Angular | Not yet a verified adapter contract | Browser mount, immutable update, and teardown |
| Lit | Not yet a verified adapter contract | Browser registration, update, disconnect, reconnect |
| Alpine | None | Browser-only directive |
For adapters with server output, the browser must render the same definition, input, dimensions, formatters, and component tree. Angular and Lit may run inside applications with their own server infrastructure, but this library does not yet promise or test adapter hydration for them.
The server cannot measure a container. Supply one of these policies:
<Chart
definition={trafficChart}
ariaLabel="Daily traffic"
initialWidth={720}
aspectRatio={16 / 9}
/>The adapter uses an explicit width before initialWidth when deriving the server height. After mounting, a responsive host observes the container and renders at its measured width. Pick an initialWidth close to the layout's common size to minimize the first responsive adjustment.
See Responsive Charts for the complete size policy.
Server and first-client output must agree for the same definition, input, size, and options. In particular:
Dynamic chart functions are synchronous. Fetch and transform data in the application's server/data layer, then pass the resolved input to the chart.
Server and browser executions create separate runtime instances. Within the browser adapter's own initial render and layout-effect mount, the DOM host receives the already created browser runtime.
Do not conditionally replace a chart with a different component only because the code is executing on the server. That creates a different tree and gives up the shared render path.
@tanstack/react-charts/canvas and @tanstack/octane-charts/canvas render a deterministic accessible shell on the server: a named chart root and two aria-hidden canvas elements with the initial scene dimensions. No server Canvas API or pixel painting is required.
The client renders the same shell, adopts its existing root and canvases, sizes their backing stores for the device-pixel ratio, paints the scene, and attaches the shared interaction host. The first image appears after client mount; use the default SVG adapter when visible server-rendered geometry is required.
Automatic guide margins depend on text metrics. The server uses deterministic fallback measurement unless you provide measureText. The browser host remeasures when fonts become available and schedules a new layout.
For strict pixel parity:
Most applications should allow the browser's post-font layout correction instead of shipping a font engine to the server.
createChartRuntime and renderChartSvg form the server boundary:
import { createChartRuntime, renderChartSvg } from '@tanstack/charts'
const runtime = createChartRuntime<TrafficRow, TrafficInput, Date, number>()
const scene = runtime.render(definition, input, { width: 720, height: 400 })
const svg = renderChartSvg(scene, {
ariaLabel: 'Daily traffic',
idPrefix: 'traffic',
})
runtime.destroy()renderChartSvg returns a string and does not require a DOM. A custom ChartRenderer.prerender may produce another deterministic shell. Browser-only focus, tooltip, reconciliation or paint, animation, and export begin when its surface mounts.
See the selected framework adapter page and Runtime and Scene for the exact contracts.