Install the framework-agnostic core in every application that authors chart definitions:
pnpm add @tanstack/chartsThen add one adapter if the application needs it:
# React
pnpm add @tanstack/react-charts react react-dom
# Preact
pnpm add @tanstack/preact-charts preact
# Vue
pnpm add @tanstack/vue-charts vue
# Solid
pnpm add @tanstack/solid-charts solid-js
# Svelte
pnpm add @tanstack/svelte-charts svelte
# Angular
pnpm add @tanstack/angular-charts @angular/core @angular/platform-browser
# Lit
pnpm add @tanstack/lit-charts lit
# Alpine
pnpm add @tanstack/alpine-charts alpinejs
# Octane
pnpm add @tanstack/octane-charts octaneThe adapters intentionally do not replace the core package. Definitions and marks still come from @tanstack/charts; an adapter only connects the shared runtime to its framework lifecycle.
| Adapter package | Framework peers |
|---|---|
| @tanstack/react-charts | React and React DOM ^19.0.0 |
| @tanstack/preact-charts | Preact >=10 |
| @tanstack/vue-charts | Vue >=3.5 |
| @tanstack/solid-charts | Solid >=1.8 |
| @tanstack/svelte-charts | Svelte ^5.20.0 |
| @tanstack/angular-charts | Angular core and platform browser >=19 |
| @tanstack/lit-charts | Lit >=3.1.3 |
| @tanstack/alpine-charts | Alpine >=3.15 |
| @tanstack/octane-charts | Octane ^0.1.13 |
These ranges are the package peer contracts. Use the selected framework's normal renderer or application package beside the adapter when the application needs browser mounting or server rendering.
TanStack Charts accepts configured D3 scales and the output of D3 transforms directly. Your application must declare every d3-* module that its source imports. Strict package managers do not expose transitive dependencies as an application import contract.
A typical cartesian chart uses:
pnpm add d3-array d3-scale
pnpm add -D @types/d3-array @types/d3-scaleAdd shape interpolation only when a chart imports it:
pnpm add d3-shape
pnpm add -D @types/d3-shapeOther capabilities remain equally granular:
# Examples: install only what the application imports
pnpm add d3-geo d3-quadtree d3-delaunay d3-selection d3-zoom d3-brush d3-time d3-scale-chromatic
pnpm add -D @types/d3-geo @types/d3-quadtree @types/d3-delaunay @types/d3-selection @types/d3-zoom @types/d3-brush @types/d3-time @types/d3-scale-chromaticDo not install the d3 umbrella package just because a chart uses one D3 capability. Named modules keep ownership visible and make the measured consumer bundle reflect the chart that was actually authored. Scales and D3 is the single guide to this boundary and links to the corresponding official D3 documentation.
The core plus a common scale-and-array setup:
# npm
npm install @tanstack/charts d3-array d3-scale
npm install --save-dev @types/d3-array @types/d3-scale
# yarn
yarn add @tanstack/charts d3-array d3-scale
yarn add --dev @types/d3-array @types/d3-scale
# pnpm
pnpm add @tanstack/charts d3-array d3-scale
pnpm add -D @types/d3-array @types/d3-scale
# bun
bun add @tanstack/charts d3-array d3-scale
bun add -D @types/d3-array @types/d3-scaleInstall exactly one adapter package and its required framework peers. A shared definition can move between adapters without changing marks, channels, scales, or captured data.
Use the package root for ordinary application authoring:
import { defineChart, lineY, mountChart } from '@tanstack/charts'Use subpath exports when an authored library needs a hard capability boundary:
import { lineY } from '@tanstack/charts/line'
import { mountChart } from '@tanstack/charts/dom'
import { renderChartSvg } from '@tanstack/charts/svg'Subpaths are not a second API. They expose the same functions without making unrelated marks, the DOM host, exporters, or framework code reachable from that entry.
Optional capabilities have explicit entries:
import { d3Curve } from '@tanstack/charts/d3/shape'
import { renderChartImage } from '@tanstack/charts/export'
import { focusX } from '@tanstack/charts/focus'
import { mountCanvasChart } from '@tanstack/charts/canvas'
import { mountChartRenderer } from '@tanstack/charts/renderer'
import { polar, radialArc } from '@tanstack/charts/polar'
import { geoShape } from '@tanstack/charts/geo'Canvas remains optional in framework code too:
import { Chart as ReactCanvasChart } from '@tanstack/react-charts/canvas'
import { Chart as ReactRendererChart } from '@tanstack/react-charts/core'
import { Chart as OctaneCanvasChart } from '@tanstack/octane-charts/canvas'
import { Chart as OctaneRendererChart } from '@tanstack/octane-charts/core'The default entries are SVG-based. React and Octane currently provide the optional /canvas and /core entries.
Polar and geographic marks are intentionally absent from the package root. Their subpaths keep d3-shape and d3-geo unreachable from ordinary Cartesian consumers.
TanStack Charts ships its own declarations. Install the matching @types/d3-* package for each D3 module your TypeScript source imports.
Normal chart authoring should not require adapter generics or casts:
import { scaleLinear } from 'd3-scale'
import { defineChart, lineY } from '@tanstack/charts'
const values = [4, 9, 7]
const chart = defineChart({
marks: [lineY(values)],
x: { scale: scaleLinear },
y: { scale: scaleLinear },
})If a channel or scale does not type-check, correct the source type, field, accessor, scale domain, or definition. The TypeScript guide covers inference and advanced custom marks.
Chart definitions, scene creation, and SVG string rendering do not require a browser. The vanilla hosts require normal DOM APIs and use ResizeObserver when width is responsive. Canvas rendering additionally requires Canvas 2D; curved, polar, and geographic path data requires Path2D. React and Octane Canvas entries emit an accessible shell on the server, then paint pixels and connect the shared host on the client.
Use initialWidth for deterministic server and hidden-container output. See SSR and Hydration for adapter-specific setup.
Create a small scene without mounting it:
import { scaleLinear } from 'd3-scale'
import { createChartScene, defineChart, lineY } from '@tanstack/charts'
const chart = defineChart({
marks: [lineY([2, 5, 3])],
x: { scale: scaleLinear },
y: { scale: scaleLinear },
})
const scene = createChartScene(chart, { width: 640, height: 320 })
console.log(scene.chart, scene.points.length)Both positional scales are required. A missing scale is an authoring error rather than a hidden fallback.
Continue with the Quick Start, then open the adapter page for the framework that owns the chart component.