TanStack Charts

TanStack

2 min read Original article ↗

TanStack

A chart grammar you don't have to outgrow.

A typed, tree-shakable chart grammar for SVG and Canvas. Compose marks, views, scales, transforms, interactions, and motion with compact primitives or D3-compatible inputs.

San Francisco temperature range band

range

Grouped bars

bar

Bubble scatterplot

relationship

All mark, no chart.

Type Safe & Declarative for both Humans & Agents

Every example compiles under strict TypeScript. Fields, datum types, inferred domains and keys, tooltips, and focus callbacks stay connected to the source datum; the type suite rejects invalid definitions.

import { scaleLinear } from '@tanstack/charts/scales/linear'
import { defineChart, dot } from '@tanstack/charts'
import { tooltip } from '@tanstack/charts/tooltip'
import { Chart } from '@tanstack/charts/react'
import { scaleSqrt } from 'd3-scale'

const accountHealth = defineChart({
  marks: [
    dot(accounts, {
      x: 'monthlyRevenue',
      y: 'retention',
      r: 'seats',
      rScale: {
        scale: () => scaleSqrt().range([4, 22]),
      },
      z: 'segment',
      key: 'id',
    }),
  ],
  x: {
    scale: scaleLinear,
    axis: { label: 'Monthly revenue ($k)' },
  },
  y: {
    scale: scaleLinear,
    axis: {
      label: '90-day retention',
      ticks: { format: (value) => percent.format(value) },
    },
  },
  tooltip,
})

export function AccountHealthChart({
  onFocus,
}: {
  onFocus: (account: Account | null) => void
}) {
  return (
    <Chart
      definition={accountHealth}
      ariaLabel="Account health by revenue, retention, segment, and seats"
      onFocusChange={(point) => onFocus(point?.datum ?? null)}
    />
  )
}

Account health

Illustrative account dataset

Which high-revenue accounts need retention attention?

EnterpriseGrowthSMBBubble size = seats

Make it look like your product.

Same data and scales. CSS variables, themes, mark props, custom tooltips, or your own renderer control the rest.

Editorial

Product

Terminal

Monokai

Compose from marks to complete views.

Layer marks when they share a coordinate system. For compound charts, composeViews places complete definitions with fill, grid, layer, and inset utilities. Each view keeps its own scales unless you share or align them. View composition reference.

TanStack Charts builds on Leland Wilkinson's grammar of graphics and the work of ggplot2, Vega-Lite, and Observable Plot. Its marks-and-channels API is most directly inspired by Observable Plot, but the runtime is an independent implementation.